8 辅助工具使用教程

备注

用DSPAW完成DFT计算后,想快速分析结果、画图,或者完成一些常见的数据处理任务?

dspawpyPython ≥ 3.9 )就是这样一款辅助工具,它可以编程调用(参考下文示例脚本),也提供了一个命令行交互程序

参考下方教程 安装 后,命令行输入 dspawpy 后回车即可使用交互程序:

 ... loading dspawpy cli ...

 ********这是dspawpy命令行交互小工具,预祝您使用愉快********
    ( )
   _| |  ___  _ _      _ _  _   _   _  _ _    _   _
 /'_` |/',__)( '_`\  /'_` )( ) ( ) ( )( '_`\ ( ) ( )
( (_| |\__, \| (_) )( (_| || \_/ \_/ || (_) )| (_) |
 \__,_)(____/| ,__/'`\__,_) \___x___/ | ,__/  \__, |
             | |                      | |    ( )_| |
             (_)                      (_)     \___/

 [版本号]: [安装路径]

 ======================================
 |  1: update更新
 |  2: structure结构转化
 |  3: volumetricData数据处理
 |  4: band能带数据处理
 |  5: dos态密度数据处理
 |  6: bandDos能带和态密度共同显示
 |  7: optical光学性质数据处理
 |  8: neb过渡态计算数据处理
 |  9: phonon声子计算数据处理
 |  10: aimd分子动力学模拟数据处理
 |  11: Polarization铁电极化数据处理
 |  12: ZPE零点振动能数据处理
 |  13: TS的热校正能
 |
 |  q: 退出
 ======================================
 --> 输入数字后回车选择功能:

亮点:

  • 自动补全: 按Tab键即可生效,有助于快速且正确地输入程序所需要的参数

  • 多线程懒加载:在等待用户输入时后台加载模块,大幅缩短等待时间;仅加载必要模块,减少内存占用

注意:

  • 在远程服务器上使用时,由于机器的磁盘读写性能不佳,可能需要较长的启动时间,极端情况下可能长达半分钟(与服务器当时的磁盘读写性能直接相关)。如果无法忍受,请在自己的电脑上安装dspawpy使用

  • 输入 dspawpy 回车后,python会先加载内建模块,完成后显示 ... loading dspawpy cli ... 提示语句,表明进入第二阶段(开始加载第三方依赖库)

  • 等待第二阶段完成后,会显示欢迎界面,此时dspwapy已完成前期加载,进入第三阶段。后续将动态根据选择的功能模块加载相应的依赖库,从而最大限度减少等待时间

8.1 安装与更新

  1. 在HZW机器上,已提前安装 dspawpy,使用以下命令激活虚拟环境即可使用:

source /data/hzwtech/profile/dspawpy.env
  1. 在其他机器上,请自行安装 dspawpy(下列两种方式二选一):

mamba install dspawpy -c conda-forge
#conda install dspawpy -c conda-forge
  • 或使用 pip3 (部分操作系统中没有pip3可执行程序,此时请尝试pip)

pip
  • pip3 是 python3 自带的包管理器

  • Linux和Mac一般自带python3和pip3。

  • Windows平台打开 microsoft store 搜索 python 安装即可

_images/python_ms_store.png

然后打开 cmd 或者 powershell 即可使用 pip。

pip3 install dspawpy

关于如何设置pip和conda镜像地址以加速安装过程,可参考 https://mirrors.tuna.tsinghua.edu.cn/help/pypi/https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/

如果安装依然失败,请尝试上面的 mamba/conda 安装法。

警告

在集群上,由于权限问题,公共路径中的pip很可能不支持全局安装python库,必须在 pip install 后面追加 --user 选项安装到家目录 ~/.local/lib/python3.x/site-packages/ 下,其中3.x表示python解释器版本,x可能是9-13之间的任意整数

python将优先读取家目录下的dspawpy,即使公共环境中的dspawpy的版本比家目录中的dspawpy的版本新! 因此,如果以前用 --user 安装过dspawpy,又忘记手动更新家目录下的老版本dspawpy,即使source了公共环境,也无法调用公共环境中的dspawpy,依旧会使用老版本dspawpy,导致一些BUG。

因此,鉴于HZW集群每周自动更新dspawpy,建议不要在家目录下重复安装,已安装的建议删除 。如果在其他集群上,请确保及时手动更新家目录下的 dspawpy

如果不想删除家目录中的dspawpy,又不想更新它,可以在运行python脚本时,尝试 -s 选项避免导入家目录中的 dspawpy: python -s your-script.py

更新 dspawpy

如果 dspawpy 是通过 mamba/conda 安装的,使用以下命令更新:

mamba update dspawpy
#conda update dspawpy

如果 dspawpy 是通过 pip 安装的,那么:

pip install dspawpy -U # -U 表示安装最新版

备注

如果 pip 使用了国内的镜像网站,可能由于镜像网站尚未同步最新版 dspawpy dspawpy_version 而导致无法顺利升级,请使用如下命令告诉 pip 从pypi官网下载安装:

pip install dspawpy -i https://pypi.org/simple --user -U # -i 指定下载地址,--user 表示仅为当前用户安装,-U 表示安装最新版

如果运行时出现 dspawpy 相关 错误信息,请先检查是否已正确导入最新版本的 dspawpy 并检查安装路径:

$ python3 # 或 python
>>> import dspawpy
>>> dspawpy.__version__ # 将输出版本号
>>> dspawpy.__file__ # 将输出安装路径

8.2 structure结构转化

读取结构信息使用 read 函数;将结构信息写入文件,使用 write 函数;快速结构转化,使用 convert 函数:

API: read(), write(), convert()
dspawpy.io.structure.convert(infile, si=None, ele=None, ai=None, infmt: str | None = None, task: str = 'scf', outfile: str = 'temp.xyz', outfmt: str | None = None, coords_are_cartesian: bool = True)

convert from infile to outfile.

  • multi -> single, only keep last step

  • crystal -> molecule, will lose lattice info

  • molecule -> crystal, will add a box of twice the maximum xyz

  • pdb, dump may suffer decimal precision loss

参数:
  • infile --

    • h5/json/as/hzw/cif/poscar/cssr/xsf/mcsqs/prismatic/yaml/fleur-inpgen file path

    • If a folder is given, will read {task}.h5/json files

    • If structures are given, will read multiple structures.

  • si (int, list, or str) --

    • Structure index, starting from 1

      • si=1, read the 1st

      • si=[1,2], read the 1st and 2nd

      • si=':', read all

      • si='-3:', read the last 3

    • If empty, for multi-configuration files, all configurations will be read; for single-configuration files, the latest configuration will be read.

    • This parameter is only valid for h5/json files.

  • ele --

    • Element symbol, written as 'H' or ['H','O']

    • If empty, atomic information for all elements will be read.

    • This parameter is only valid for h5/json files.

  • ai --

    • Atom index, starting from 1

    • Usage is the same as si

    • If empty, atomic information for all atoms will be read.

    • This parameter is only valid for h5/json files.

  • infmt --

    • Input structure file type, e.g., 'h5'. If None, the file extension will determine the format.

  • task --

    • Used when datafile is a folder path to locate the internal {task}.h5/json file.

    • Calculation task type, including 'scf', 'relax', 'neb', 'aimd'. Other values will be ignored.

  • outfile --

    • Output filename

  • outfmt --

    • Output structure file type, e.g., 'xyz'. If None, the file extension will determine the format.

  • coords_are_cartesian --

    • Whether to write coordinates in Cartesian form (default: True); otherwise, fractional coordinates will be used.

    • This option is currently only valid for as and json formats.

示例

>>> from dspawpy.io.structure import convert
>>> convert('dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.as', outfile='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.hzw')
==> ...PtH.hzw...

batch test

>>> for readable in ['relax.h5', 'system.json', 'aimd.pdb', 'latestStructure.as', 'CuO.hzw', 'POSCAR']:
...     for writable in ['pdb', 'xyz', 'dump', 'as', 'hzw', 'POSCAR']:
...         convert('dspawpy_proj/dspawpy_tests/inputs/supplement/stru/'+readable, outfile=f"dspawpy_proj/dspawpy_tests/outputs/doctest/{readable.split('.')[0]}.{writable}")
==> ...relax.pdb...
==> ...relax.xyz...
==> ...relax.dump...
==> ...relax.as...
==> ...relax.hzw...
==> ...system.pdb...
==> ...system.xyz...
==> ...system.dump...
==> ...system.as...
==> ...system.hzw...
==> ...aimd.pdb...
==> ...aimd.xyz...
==> ...aimd.dump...
==> ...aimd.as...
==> ...aimd.hzw...
==> ...latestStructure.pdb...
==> ...latestStructure.xyz...
==> ...latestStructure.dump...
==> ...latestStructure.as...
==> ...latestStructure.hzw...
==> ...CuO.pdb...
==> ...CuO.xyz...
==> ...CuO.dump...
==> ...CuO.as...
==> ...CuO.hzw...
==> ...POSCAR.pdb...
==> ...POSCAR.xyz...
==> ...POSCAR.dump...
==> ...POSCAR.as...
==> ...POSCAR.hzw...
dspawpy.io.structure.read(datafile: str | list, si=None, ele=None, ai=None, fmt: str | None = None, task: str | None = 'scf')

Read one or more h5/json files and return a list of pymatgen Structures.

参数:
  • datafile --

    • file paths for h5/json/as/hzw/cif/poscar/cssr/xsf/mcsqs/prismatic/yaml/fleur-inpgen files;

    • If a directory path is given, it can be combined with the task parameter to read the {task}.h5/json files inside

    • If a list of strings is given, it will sequentially read the data and merge them into a list of Structures

  • si (int, list or str) --

    • Configuration number, starting from 1

      • si=1, reads the first configuration

      • si=[1,2], reads the first and second configurations

      • si=':', reads all configurations

      • si='-3:', reads the last three configurations

    • If empty, it reads all configurations for multi-configuration files and the latest configuration for single-configuration files

    • This parameter is only valid for h5/json files

  • ele --

    • Element symbol, format reference: 'H' or ['H','O']

    • If empty, it will read atomic information for all elements

    • This parameter is only valid for h5/json files

  • ai --

    • Atom index, starting from 1

    • Same as si

    • If empty, it will read all atom information

    • This parameter is only valid for h5/json files

  • fmt --

    • File format, including 'as', 'hzw', 'xyz', 'pdb', 'h5', 'json' 6 types, other values will be ignored.

    • If empty, the file type will be determined based on file name conventions.

  • task --

    • Used when datafile is a directory path to find the internal {task}.h5/json file.

    • Determine the task type, including 'scf', 'relax', 'neb', 'aimd' four types, other values will be ignored.

返回:

Structure list

返回类型:

pymatgen_Structures

示例

>>> from dspawpy.io.structure import read

Reads a single file to generate a list of Structures

>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.as')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/PtH.hzw')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/Si2.xyz')
>>> len(pymatgen_Structures)
1
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/supplement/aimd.pdb')
>>> len(pymatgen_Structures)
1000
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/2.1/relax.h5')
>>> len(pymatgen_Structures)
3
>>> pymatgen_Structures = read(datafile='dspawpy_proj/dspawpy_tests/inputs/2.1/relax.json')
>>> len(pymatgen_Structures)
3

Note that pymatgen_Structures is a list composed of multiple Structure objects, each corresponding to a structure. If there is only one structure, it will also return a list. Please use pymatgen_Structures[0] to obtain the Structure object.

When datafile is a list, it reads multiple files sequentially and merges them into a Structures list

>>> pymatgen_Structures = read(datafile=['dspawpy_proj/dspawpy_tests/inputs/supplement/aimd1.h5','dspawpy_proj/dspawpy_tests/inputs/supplement/aimd2.h5'])
dspawpy.io.structure.write(structure, filename: str, fmt: str | None = None, coords_are_cartesian: bool = True)

Write information to the structure file

参数:
  • structure -- A pymatgen Structure object

  • filename -- Structure filename

  • fmt --

    • Structure file type, natively supports 'json', 'as', 'hzw', 'pdb', 'xyz', 'dump' six types

  • coords_are_cartesian --

    • Whether to write in Cartesian coordinates, default is True; otherwise write in fractional coordinate format

    • This option is currently only effective for 'as' and 'json' formats

示例

First, read the structure information:

>>> from dspawpy.io.structure import read
>>> s = read('dspawpy_proj/dspawpy_tests/inputs/2.15/01/neb01.h5')
>>> len(s)
17

Writing structure information to a file:

>>> from dspawpy.io.structure import write
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.json', coords_are_cartesian=True)
==> ...PtH.json...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.as', coords_are_cartesian=True)
==> ...PtH.as...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.hzw', coords_are_cartesian=True)
==> ...PtH.hzw...

PDB, XYZ, and DUMP file types can write multiple conformations to form a "trajectory." The generated XYZ trajectory files can be opened and visualized using visualization software like OVITO.

>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.pdb', coords_are_cartesian=True)
==> ...PtH.pdb...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.xyz', coords_are_cartesian=True)
==> ...PtH.xyz...
>>> write(s, filename='dspawpy_proj/dspawpy_tests/outputs/doctest/PtH.dump', coords_are_cartesian=True)
==> ...PtH.dump...

The recommended format for storing single structure information is as format. If the Structure contains magnetic moment or degree of freedom information, it will be written in the most complete format, such as Fix_x, Fix_y, Fix_z, Mag_x, Mag_y, Mag_z. The default value for degree of freedom information is F, and the default value for magnetic moment is 0.0. You can manually delete this default information from the generated as file as needed. Writing to other types of structure files will ignore magnetic moment and degree of freedom information.

可参考 2conversion.py 脚本完成转化:

 1# coding:utf-8
 2from dspawpy.io.structure import convert
 3
 4convert(
 5    infile="dspawpy_proj/dspawpy_tests/inputs/2.1/relax.h5",  # Structure to be converted, if in the current path, you can just write the filename
 6    si=None,  # Select configuration number, if not specified, read all by default
 7    ele=None,  # Filter element symbol, default reads atomic information for all elements
 8    ai=None,  # Filter atomic indices, starting from 1, default to read all atomic information
 9    infmt=None,  # Input structure file type, e.g., 'h5'. If None, it will be matched ambiguously based on the filename rule.
10    task="relax",  # Task type, this parameter is only valid when infile is a folder rather than a filename
11    outfile="dspawpy_proj/dspawpy_tests/outputs/us/relaxed.xyz",  # Structure file name
12    outfmt=None,  # Output structure file type, e.g., 'xyz'. If None, it will be fuzzy matched according to filename rules.
13    coords_are_cartesian=True,  # Written in Cartesian coordinates by default
14)

convert 函数的几个关键参数设置规则见下表:

dspawpy 支持读写的结构文件列表

infmt(输入文件格式)

infile(输入文件名模糊匹配)

outfmt(输出文件格式)

outfile(输出文件名模糊匹配)

说明

h5

*.h5

X

X

DS-PAW计算完成后保存的hdf5类型文件

json

*.json

json

*.json

DS-PAW计算完成后保存的json类型文件

pdb

*.pdb

pdb

*.pdb

Protein Data Bank

as

*.as

as

*.as

DS-PAW记载原子坐标等信息的结构文件

hzw

*.hzw

hzw

*.hzw

DeviceStudio默认的结构文件

xyz

*.xyz

xyz

*.xyz

读取时仅支持分子结构的单构型,写入时则是包含晶胞的extended-xyz类型轨迹文件

X

X

dump

*.dump

lammps-dump类型轨迹文件

X

*.cif*/*.mcif*

cif/mcif

*.cif*/*.mcif*

Crystallographic Information File

X

*POSCAR*/*CONTCAR*/*.vasp/CHGCAR*/LOCPOT*/vasprun*.xml*

poscar

*POSCAR*

VASP文件

X

*.cssr*

cssr

*.cssr*

Crystal Structure Standard Representation

X

*.yaml/*.yml

yaml/yml

*.yaml/*.yml

YAML Ain't Markup Language

X

*.xsf*

xsf

*.xsf*

eXtended Structural Format

X

*rndstr.in*/*lat.in*/*bestsqs*

mcsqs

*rndstr.in*/*lat.in*/*bestsqs*

Monte Carlo Special Quasirandom Structure

X

inp*.xml/*.in*/inp_*

fleur-inpgen

*.in*

FLEUR 结构文件,须额外安装 pymatgen-io-fleur 库

X

*.res

res

*.res

ShelX res 结构文件

X

*.config*/*.pwmat*

pwmat

*.config/*.pwmat

PWmat 文件

X

X

prismatic

*prismatic*

用于STEM模拟的一种文件格式

X

CTRL*

X

X

Stuttgart LMTO-ASA 文件

备注

  • 上述表格中 * 号表示任意字符,X 表示不支持

  • h5, json, pdb, xyz, dump, CONTCAR等格式支持多个结构组成的轨迹信息(常见于结构优化或者NEB或者AIMD任务)

  • in(out)fmt 参数优先级高于文件名模糊匹配规则;例如,指定 in(out)fmt='h5' 后,文件名可以是任意值,甚至可以是 a.json

  • 将结构信息写为 json 格式时,仅支持可视化 NEB 链任务,详见 观察NEB链 节相关说明

  • DS-PAW 输出的 neb.h5、phonon.h5、phonon.json、neb.json以及wannier.json 暂时无法读取结构信息

8.3 volumetricData数据处理

volumetricData可视化

  • 参考 3vis_vol.py

     1# coding:utf-8
     2from dspawpy.io.write import write_VESTA
     3
     4# Read data file (in h5 or json format), process it, and output to a cube file
     5write_VESTA(
     6    in_filename="dspawpy_proj/dspawpy_tests/inputs/2.2/rho.h5",  # Path to the json or h5 file containing electronic system information
     7    data_type="rho",  # Data type, supported values are "rho", "potential", "elf", "pcharge", "rhoBound"
     8    out_filename="dspawpy_proj/dspawpy_tests/outputs/us/DS-PAW_rho.cube",  # Output file path
     9    gridsize=(10, 10, 10),  # Specifies the interpolation grid size
    10    format="cube",  # Supported formats: cube, vesta, and txt (xyz grid coordinates + values)
    11)
    

    将转换后的文件 DS-PAW_rho.cube 拖入 VESTA 软件中显示:

    _images/1-3.png

    晶体硅单胞的电荷密度分布示意图

差分volumetricData可视化

  • 参考 3dvol.py

     1# coding:utf-8
     2from dspawpy.io.write import write_delta_rho_vesta
     3
     4# Read the data file (h5 or json format), process it, and output it to a cube file, which can be directly opened with Vesta and has a small volume
     5write_delta_rho_vesta(
     6    total="dspawpy_proj/dspawpy_tests/inputs/supplement/AB.h5",  # Data file for the system containing all components
     7    individuals=[
     8        "dspawpy_proj/dspawpy_tests/inputs/supplement/A.h5",
     9        "dspawpy_proj/dspawpy_tests/inputs/supplement/B.h5",
    10    ],  # Data files for the system containing each component
    11    output="dspawpy_proj/dspawpy_tests/outputs/us/3delta_rho.cube",  # Output file path
    12)
    

    上述脚本支持处理多元体系的电荷密度差,示例以二元体系为例,得到了 AB.h5 与 A.h5 和 B.h5 之间的电荷密度差文件 delta_rho.cube ,该文件可直接使用 VESTA 打开。

volumetricData面平均

 1# coding:utf-8
 2from dspawpy.plot import average_along_axis
 3
 4axes = [
 5    "2"
 6]  # "0", "1", "2" correspond to the x, y, z axes respectively; select which axes to average along
 7axes_indices = [int(i) for i in axes]
 8for ai in axes_indices:
 9    plt = average_along_axis(
10        datafile="dspawpy_proj/dspawpy_tests/inputs/3.3/scf.h5",  # Data file path
11        task="potential",  # Task name, can be 'rho', 'potential', 'elf', 'pcharge', 'rhoBound'
12        axis=ai,  # Axis along which to plot the potential curve
13        smooth=False,  # Whether to smooth
14        smooth_frac=0.8,  # Smoothing coefficient
15        subtype=None,  # Used to specify the subclass of task data, currently only used for Potential
16        label=f"axis{ai}",  # Legend label
17    )
18if len(axes_indices) > 1:
19    plt.legend()
20
21plt.xlabel("Grid Index")
22plt.ylabel("TotalElectrostaticPotential (eV)")
23plt.savefig("dspawpy_proj/dspawpy_tests/outputs/us/3pot_ave.png", dpi=300)  # Image name

处理 应用案例 3.3 小节所得静电势文件,可得真空方向势函数曲线如下所示:

_images/3pot_ave.png

AuAl势函数示意图

API: write_VESTA(), write_delta_rho_vesta(), average_along_axis()
  • write_VESTA 函数负责处理volumetricData可视化:

    dspawpy.io.write.write_VESTA(in_filename: str, data_type: str, out_filename: str = 'DS-PAW.cube', subtype: str | None = None, format: str | None = 'cube', compact: bool = False, inorm: bool = False, gridsize: Sequence[int] | None = None)

    Read data from a json or h5 file containing electronic system information and write to a VESTA formatted file.

    参数:
    • in_filename -- Path to a json or h5 file containing electronic system information

    • data_type -- Data type, supported values are "rho", "potential", "elf", "pcharge", "rhoBound"

    • out_filename -- Output file path, default "DS-PAW.cube"

    • subtype -- Used to specify the subtype of data_type, default is None, which will read the TotalElectrostaticPotential data of potential

    • format -- Output data format, supports "cube" and "vesta" ("vasp"), default is "cube", case-insensitive

    • compact -- Each data point for each grid is placed on a new line, reducing the file size by decreasing the number of spaces (this does not affect the parsing of VESTA software), default is False

    • inorm -- Whether to normalize the volume data so that the sum is 1, default is False

    • gridsize -- The redefined number of grid points, in the format (ngx, ngy, ngz), default is None, which uses the original number of grid points

    返回:

    VESTA formatted file

    返回类型:

    out_filename

    示例

    >>> from dspawpy.io.write import write_VESTA
    >>> write_VESTA("dspawpy_proj/dspawpy_tests/inputs/2.2/rho.json", "rho", out_filename='dspawpy_proj/dspawpy_tests/outputs/doctest/rho.cube')
    ==> ...rho.cube...
    
    >>> from dspawpy.io.write import write_VESTA
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.cube",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... )
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.cube...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5",
    ...     data_type="elf",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/elf.cube",
    ... )
    ==> ...elf.cube...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5",
    ...     data_type="pcharge",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge.cube",
    ... )
    ==> ...pcharge.cube...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.vasp",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... )
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.vasp...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5",
    ...     data_type="elf",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/elf.vasp",
    ... )
    ==> ...elf.vasp...
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5",
    ...     data_type="pcharge",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge.vasp",
    ... )
    ==> ...pcharge.vasp...
    
    >>> write_VESTA(
    ...     in_filename="dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5",
    ...     data_type="potential",
    ...     out_filename="dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.txt",
    ...     subtype='TotalElectrostaticPotential', # or 'TotalLocalPotential'
    ...     gridsize=(50,50,50), # all integer, can be larger or less than the original gridsize
    ... )
    Interpolating volumetric data...
    volumetric data interpolated
    ==> ...my_potential.txt...
    >>> with open("dspawpy_proj/dspawpy_tests/outputs/doctest/my_potential.txt") as t:
    ...     contents = t.readlines()
    ...     for line in contents[:10]:
    ...         print(line.strip())
    # 2 atoms
    # 50 50 50 grid size
    # x y z value
    0.000 0.000 0.000      0.3279418
    0.055 0.055 0.000     -0.0740864
    0.110 0.110 0.000     -0.8811763
    0.165 0.165 0.000     -2.1283865
    0.220 0.220 0.000     -4.0559145
    0.275 0.275 0.000     -6.8291030
    0.330 0.330 0.000    -10.1550909
    

volumetricData 指的是随空间位置变化的物理量,如电荷密度 rho,势能函数 potential,局域电荷密度 elf,部分电荷密度 pcharge,溶剂束缚电荷密度 rhoBound 等。这些数据在 DS-PAW 中以 volumetricData 类型保存。

  • write_delta_rho_vesta 函数负责处理差分volumetricData可视化:

    dspawpy.io.write.write_delta_rho_vesta(total: str, individuals: list[str], output: str = 'delta_rho.cube', format: str = 'cube', compact: bool = False, inorm: bool = False, gridsize: Sequence | None = None, data_type: str | None = 'rho', subtype: str | None = None)

    Charge density differential visualization

    DeviceStudio does not currently support large files; it is temporarily written in a format that can be opened with VESTA.

    参数:
    • total -- Path to the total charge density file of the system, can be in h5 or json format

    • individuals -- Paths to the charge density files of each component in the system, can be in h5 or json format

    • output -- Output file path, default "delta_rho.cube"

    • format -- Output data format, supports "cube" and "vasp", default to "cube"

    • compact -- Each data point for each grid is placed on a new line, and the file size is reduced by reducing the number of spaces (this does not affect the parsing by VESTA software), default is False

    • inorm -- Whether to normalize the volume data so that the sum is 1, default is False

    • gridsize -- Redefined grid number, format as (ngx, ngy, ngz), default is None, use the original grid number

    返回:

    A charge density file after the difference of charges (total - individual1 - individual2 - ...)

    返回类型:

    output

    示例

    >>> from dspawpy.io.write import write_delta_rho_vesta
    >>> write_delta_rho_vesta(total='dspawpy_proj/dspawpy_tests/inputs/supplement/AB.h5',
    ...     individuals=['dspawpy_proj/dspawpy_tests/inputs/supplement/A.h5', 'dspawpy_proj/dspawpy_tests/inputs/supplement/B.h5'],
    ...     output='dspawpy_proj/dspawpy_tests/outputs/doctest/delta_rho.cube')
    ==> ...delta_rho.cube...
    
  • average_along_axis 函数负责处理volumetricData面平均数据:

    dspawpy.plot.average_along_axis(datafile: str = 'potential.h5', task: str = 'potential', axis: int = 2, smooth: bool = False, smooth_frac: float = 0.8, raw: bool = False, subtype: str | None = None, verbose: bool = False, **kwargs)

    Plot the average curve of a physical quantity along a certain axis

    参数:
    • datafile -- Path to an h5 or json file, or a folder containing any of these files, default 'potential.h5'

    • task -- Task type, can be 'rho', 'potential', 'elf', 'pcharge', 'rhoBound'

    • axis -- Along which axis to plot the potential curve, default is 2

    • smooth -- Whether to smooth, default False

    • smooth_frac -- Smoothing coefficient, default 0.8

    • raw -- Whether to return plot data to a CSV file

    • subtype -- Used to specify the task data subtype, default None, representing drawing Potential/TotalElectrostaticPotential

    • **kwargs -- Other parameters, passed to matplotlib.pyplot.plot

    返回:

    Can be passed to other functions for further processing

    返回类型:

    axes

    示例

    >>> from dspawpy.plot import average_along_axis
    

    Read data from the potential.h5 file, plot, and save the original plot data to a CSV file

    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/3.3/rho.h5', task='rho', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rho_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/3.3/rho.json', task='rho', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rho_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.7/potential.h5', task='potential', axis=2, smooth=True, smooth_frac=0.8, raw=True)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/potential_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.7/potential.json', task='potential', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/potential_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.8/elf.h5', task='elf', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/elf_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.8/elf.json', task='elf', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/elf_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.h5', task='pcharge', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.9/pcharge.json', task='pcharge', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/pcharge_json.png')
    
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.28/rhoBound.h5', task='rhoBound', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rhoBound_h5.png')
    >>> plt = average_along_axis(datafile='dspawpy_proj/dspawpy_tests/inputs/2.28/rhoBound.json', task='rhoBound', axis=2, smooth=True, smooth_frac=0.8)
    >>> plt.savefig('dspawpy_proj/dspawpy_tests/outputs/doctest/rhoBound_json.png')
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.4 band能带数据处理

知识点:

  1. 脚本中调用get_band_data()读取数据,在读取数据时设置efermi=XX可将能量零点修改为指定值;设置zero_to_efermi=True, 可将能量零点修改问所读取的文件中的费米能级处

  2. 脚本调用pymatgen的BSPlotter.get_plot()画图,在画图时可设置zero_to_efermi=True,将坐标轴能量零点修改到费米能级处。由于pymatgen在2023.8.17的一处关键更新将绘图函数返回对象从plt改成了axes,导致后续脚本可能出现不兼容。因此用户脚本相关部分已添加一个判断语句加以处理。

  3. 能带两步算需从第一步自洽计算获取准确费米能级(从自洽获得的system.json),若获取失败,用户可在调用get_band_data读取数据时,利用参数efermi修改能量零点。例如:band_data=get_band_data('band.h5',efermi=-1.5)

  4. 脚本中画图调用pymatgen中的BSPlotter.get_plot, 当判断体系为非金属时,设置zero_to_efermi会认为VBM为费米能级能量而非文件读取时的费米能级。故当体系为非金属时,在数据读取时设置zero_to_efermi=True和在画图时设置zero_to_efermi=True得到的图会有区别

执行本节所列的python脚本,程序会判断是否为金属体系。若为非金属体系,将要求选择是否平移费米能级到能量零点,请按提示操作。

如有必要,参考 export_band.py 将能带数据提取出来并写入csv文件:

 1# coding:utf-8
 2from dspawpy.io.export import read_band
 3
 4band_data = read_band(
 5    bandfile="dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5",
 6    mode=1,  # projection mode, only valid for pband data
 7    hide_index=False,  # hide index column or not
 8    fmt="8.3f",  # decimal format to print
 9)
10band_data.write_csv("banddata.csv")

投影模式 mode 可以设置成 1~5 ,分别对应

  1. 元素

  2. 元素 + spdf 轨道

  3. 元素 + spxpypz... 轨道

  4. 原子 + spdf 轨道

  5. 原子 + spxpypz... 轨道

其中,4、5两种投影模式输出的数据表格中,第一个数字表示能带编号,第二个数字表示原子编号,都从 1 开始;比如 2-1-s 表示第二条能带中第一个原子的s轨道贡献

API: read_band()
dspawpy.io.export.read_band(bandfile: str | Path, mode: int = 5, hide_index: bool = False, fmt: str = '8.3f')

Construct a dataframe of band structure data from an h5 or json file.

参数:
  • bandfile (str | Path) -- band data file location, such as 'band.json'.

  • mode (int) -- which projection mode, only valid for pband data.

  • hide_index (bool) -- hide index column in dataframe or not.

  • fmt (str) -- control display decimal, such as '8.3f'

示例

>>> from dspawpy.io.export import read_band
>>> read_band(bandfile='dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5')
efermi=5.1696 eV
shape: (150, 16)
┌───────┬──────────┬──────────┬──────────┬───┬──────────┬──────────┬──────────┬──────────┐
│ index ┆ kx       ┆ ky       ┆ kz       ┆ … ┆ 9        ┆ 10       ┆ 11       ┆ 12       │
╞═══════╪══════════╪══════════╪══════════╪═══╪══════════╪══════════╪══════════╪══════════╡
│ 1     ┆    0.000 ┆    0.500 ┆    0.246 ┆ … ┆   -4.950 ┆    7.858 ┆   -6.766 ┆    8.395 │
│ 2     ┆    0.000 ┆    0.172 ┆    0.246 ┆ … ┆   -0.491 ┆    9.558 ┆    3.944 ┆   12.139 │
│ 3     ┆    0.000 ┆    0.672 ┆    0.491 ┆ … ┆    1.294 ┆   11.707 ┆    4.708 ┆   12.457 │
│ 4     ┆    0.017 ┆    0.500 ┆    0.233 ┆ … ┆    3.604 ┆   12.532 ┆    4.708 ┆   12.457 │
│ 5     ┆    0.000 ┆    0.181 ┆    0.233 ┆ … ┆    7.334 ┆   13.710 ┆    7.369 ┆   13.616 │
│ …     ┆ …        ┆ …        ┆ …        ┆ … ┆ …        ┆ …        ┆ …        ┆ …        │
│ 146   ┆    0.155 ┆    0.272 ┆    0.483 ┆ … ┆    3.067 ┆    8.304 ┆    0.255 ┆   12.534 │
│ 147   ┆    0.655 ┆    0.543 ┆    0.483 ┆ … ┆    3.906 ┆   12.505 ┆    3.982 ┆   15.529 │
│ 148   ┆    0.500 ┆    0.259 ┆    0.500 ┆ … ┆    4.713 ┆   12.505 ┆    3.982 ┆   15.942 │
│ 149   ┆    0.164 ┆    0.259 ┆    0.500 ┆ … ┆    7.675 ┆   12.908 ┆    6.606 ┆   16.040 │
│ 150   ┆    0.664 ┆    0.517 ┆    0.500 ┆ … ┆    7.700 ┆   16.401 ┆    8.395 ┆   17.259 │
└───────┴──────────┴──────────┴──────────┴───┴──────────┴──────────┴──────────┴──────────┘

普通能带处理

参考 4bandplot.py

 1# coding:utf-8
 2import os
 3import matplotlib.pyplot as plt
 4from pymatgen.electronic_structure.plotter import BSPlotter
 5
 6from dspawpy.io.read import get_band_data
 7
 8datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specifies the data file path
 9band_data = get_band_data(
10    band_dir=datafile,
11    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
12    efermi=None,  # Used for manually correcting the Fermi level
13    zero_to_efermi=True,  # For non-metallic systems, the zero point energy should be shifted to the Fermi level
14)
15
16bsp = BSPlotter(band_data)
17axes_or_plt = bsp.get_plot(
18    zero_to_efermi=False,  # The data has already been shifted when read, so this should be turned off
19    ylim=[-10, 10],  # Range of the y-axis for the band structure plot
20    smooth=False,  # Whether to smooth the band structure plot
21    vbm_cbm_marker=False,  # Whether to mark the valence band maximum and conduction band minimum in the band structure plot
22    smooth_tol=0,  # Threshold for smoothing
23    smooth_k=3,  # Order of the smoothing process
24    smooth_np=100,  # Number of points for smoothing
25)
26
27if isinstance(axes_or_plt, plt.Axes):
28    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
29else:
30    fig = axes_or_plt.gcf()  # older version pymatgen
31
32# Add a reference line for the energy zero point
33for ax in fig.axes:
34    ax.axhline(0, lw=2, ls="-.", color="gray")
35
36figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot.png"  # Filename for the output band plot
37os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
38fig.savefig(figname, dpi=300)

知识点:

能带两步算需从自洽计算获取准确的费米能级(从system.json获取),若获取失败,用户可在 get_band_data 函数中指定 efermi 参数修改

执行代码可以得到类似以下能带图:

_images/4bandplot.png

二硫化钼能带示意图

将能带投影到每一种元素分别作图,数据点大小表示该元素对该轨道的贡献

参考 4bandplot_elt.py

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5import numpy as np
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8from dspawpy.io.read import get_band_data
 9
10datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specify the data file path
11band_data = get_band_data(
12    band_dir=datafile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
14    efermi=None,  # Used to manually adjust the Fermi level
15    zero_to_efermi=True,  # For non-metallic systems, shift the zero-point energy to the Fermi level
16)
17
18bsp = BSPlotterProjected(bs=band_data)  # Initialize the BSPlotterProjected class
19axes_or_plt = bsp.get_elt_projected_plots(
20    zero_to_efermi=False,  # The data has already been shifted when read, so this should be disabled
21    ylim=[-8, 5],  # Set the energy range
22    vbm_cbm_marker=False,  # Whether to mark the conduction band minimum (CBM) and valence band maximum (VBM)
23)
24
25if isinstance(axes_or_plt, plt.Axes):
26    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
27elif np.iterable(axes_or_plt):
28    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
29else:
30    fig = axes_or_plt.gcf()  # older version pymatgen
31
32# Add a reference line for the energy zero point
33for ax in fig.axes:
34    ax.axhline(0, lw=2, ls="-.", color="gray")
35
36figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot_elt.png"  # The filename for the output band plot
37os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
38fig.savefig(figname, dpi=300)

知识点:

  1. 用户如果需要绘制能带投影的数据,此时需要使用 BSPlotterProjected模块

  2. 使用 BSPlotterProjected模块中 get_elt_projected_plots 函数能够绘制每种元素对轨道贡献的能带图

执行代码可以得到类似以下能带图:

_images/4bandplot_elt.png

二硫化钼元素投影能带示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

能带投影到不同元素的不同轨道

参考 4bandplot_elt_orbit.py

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5import numpy as np
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8from dspawpy.io.read import get_band_data
 9
10datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specify the data file path
11band_data = get_band_data(
12    band_dir=datafile,
13    syst_dir=None,  # path to system.json file, only required when band_dir is a json file
14    efermi=None,  # Used for manually correcting the Fermi level
15    zero_to_efermi=True,  # For non-metallic systems, shift the zero point energy to the Fermi level
16)
17
18bsp = BSPlotterProjected(bs=band_data)  # Initialize the BSPlotterProjected class
19# Select elements and orbitals, create a dictionary
20dict_elem_orbit = {"Mo": ["d"], "S": ["s"]}
21
22axes_or_plt = bsp.get_projected_plots_dots(
23    dictio=dict_elem_orbit,
24    zero_to_efermi=False,  # The data has already been shifted when read, so this should be turned off
25    ylim=[-8, 5],  # Set the energy range
26    vbm_cbm_marker=False,  # Whether to mark the conduction band minimum and valence band maximum
27)
28
29if isinstance(axes_or_plt, plt.Axes):
30    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
31elif np.iterable(axes_or_plt):
32    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
33else:
34    fig = axes_or_plt.gcf()  # older version pymatgen
35
36# Add a reference line for the energy zero point
37for ax in fig.axes:
38    ax.axhline(0, lw=2, ls="-.", color="gray")
39
40figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandplot_elt_orbit.png"  # Filename for the output band plot
41os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
42fig.savefig(figname, dpi=300)

知识点:

  1. 使用 BSPlotterProjected模块中 get_projected_plots_dots可以让用户来自定义需要绘制的某种元素某种轨道(L)的能带图

  2. 例如 get_projected_plots_dots ({'Mo':['d'],'S':['s']})就是绘制Mo的d轨道和S的s轨道

执行代码可以得到类似以下能带图:

_images/4bandplot_elt_orbit.png

二硫化钼元素轨道投影能带示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将能带投影到不同原子的不同轨道

参考 4bandplot_patom_porbit.py

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5import numpy as np
 6from pymatgen.electronic_structure.plotter import BSPlotterProjected
 7
 8from dspawpy.io.read import get_band_data
 9
10datafile = "dspawpy_proj/dspawpy_tests/inputs/supplement/pband.h5"  # Specify the data file path
11band_data = get_band_data(
12    band_dir=datafile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a JSON file
14    efermi=None,  # Used to manually adjust the Fermi level
15    zero_to_efermi=True,  # For non-metallic systems, shift the zero point energy to the Fermi level
16)
17
18bsp = BSPlotterProjected(bs=band_data)
19# Specify elements, orbitals, and atomic numbers
20dict_elem_orbit = {"Mo": ["px", "py", "pz"]}
21dict_elem_index = {"Mo": [1]}
22
23axes_or_plt = bsp.get_projected_plots_dots_patom_pmorb(
24    dictio=dict_elem_orbit,  # Specify the element-orbit dictionary
25    dictpa=dict_elem_index,  # Specify the element-atomic number dictionary
26    sum_atoms=None,  # Whether to sum over atoms
27    sum_morbs=None,  # Whether to sum orbitals
28    zero_to_efermi=False,  # Data has already been shifted during reading, should be turned off here
29    ylim=None,  # Set the energy range
30    vbm_cbm_marker=False,  # Whether to mark the conduction band minimum and valence band maximum
31    selected_branches=None,  # Specify the energy band branches to be plotted
32    w_h_size=(12, 8),  # Set image width and height
33    num_column=None,  # Number of images displayed per row
34)
35
36if isinstance(axes_or_plt, plt.Axes):
37    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
38elif np.iterable(axes_or_plt):
39    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
40else:
41    fig = axes_or_plt.gcf()  # older version pymatgen
42
43# Add a reference line for the energy zero point
44for ax in fig.axes:
45    ax.axhline(0, lw=2, ls="-.", color="gray")
46
47figname = " dspawpy_proj/dspawpy_tests/outputs/us/4band_patom_porbit.png"  # Output bandpass figure filename
48os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
49fig.savefig(figname, dpi=300)

知识点:

  1. 使用 BSPlotterProjected模块中 get_projected_plots_dots_patom_pmorb 的自由度更高,可以让用户来自定义需要绘制的某些原子某些轨道的能带图

  2. dictpa指定原子,dictio 指定该原子的轨道

  3. 如果要将一些原子或一些轨道的投影分量叠加起来,请根据 get_projected_plots_dots_patom_pmorb 函数文档指定 sum_atoms 或 sum_morbs 参数

警告

  1. 如果只选择单个轨道,且轨道名称不止一个字母(例如px、dxy、dxz),get_projected_plots_dots_patom_pmorb 函数将报错,详情见 此处

执行代码可以得到类似以下能带图:

_images/4band_patom_porbit.png

二硫化钼原子投影能带示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

能带反折叠处理

参考 4bandunfolding.py

 1# coding:utf-8
 2import os
 3
 4from dspawpy.plot import plot_bandunfolding
 5
 6plt = plot_bandunfolding(
 7    datafile="dspawpy_proj/dspawpy_tests/inputs/2.22.1/band.h5",  # Read data
 8    ef=None,  # Fermi level, read from the file
 9    de=0.05,  # Band width, default 0.05
10    dele=0.06,  # Band gap, default 0.06
11)
12
13plt.ylim(-15, 10)
14figname = "dspawpy_proj/dspawpy_tests/outputs/us/4bandunfolding.png"  # Output band structure plot filename
15os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
16plt.savefig(figname, dpi=300)
17# plt.show()

执行代码可以得到类似以下能带图:

_images/4bandunfolding.png

Cu3Au能带反折叠示意图

警告

此功能暂不支持将非金属材料的费米能级设为能量零点(默认价带顶为能量零点)。

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

band-compare能带对比图处理

将普通能带和wannier能带绘制在同一张图上

参考 4bandcompare.py

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import BSPlotter
 5
 6from dspawpy.io.read import get_band_data
 7
 8band_data = get_band_data(
 9    band_dir="dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.h5",  # Wannier band file path
10    syst_dir=None,  # system.json file path, only needed when band_dir is a json file
11    efermi=None,  # Used for manually adjusting the Fermi level
12    zero_to_efermi=False,  # Whether to shift zero energy to the Fermi level
13)
14bsp = BSPlotter(bs=band_data)
15band_data = get_band_data(
16    band_dir="dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5",  # Read DFT band structure
17    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
18    efermi=None,  # Used for manually correcting the Fermi level
19    zero_to_efermi=False,  # Whether to shift the zero point energy to the Fermi level
20)
21
22bsp2 = BSPlotter(bs=band_data)
23bsp.add_bs(bsp2._bs)
24axes_or_plt = bsp.get_plot(
25    zero_to_efermi=True,  # Move the zero energy level to the Fermi level
26    ylim=[-10, 10],  # Energy band plot y-axis range
27    smooth=False,  # Whether to smooth the band structure plot
28    vbm_cbm_marker=False,  # Whether to mark the valence band maximum and conduction band minimum in the band structure plot
29    smooth_tol=0,  # Threshold for smoothing
30    smooth_k=3,  # Order of the smoothing process
31    smooth_np=100,  # Number of points for smoothing
32    bs_labels=["wannier interpolated", "DFT"],  # Band structure labels
33)
34
35import matplotlib.pyplot as plt  # noqa: E402
36
37if isinstance(axes_or_plt, plt.Axes):
38    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
39else:
40    fig = axes_or_plt.gcf()  # older version pymatgen
41
42# Add a reference line for the energy zero point
43for ax in fig.axes:
44    ax.axhline(0, lw=2, ls="-.", color="gray")
45
46figname = "dspawpy_proj/dspawpy_tests/outputs/us/4wanierBand.png"  # File name for the output band structure plot
47os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
48fig.savefig(figname, dpi=300)

执行代码可得到类似如下能带对比曲线:

_images/wannier_band.png

晶体硅瓦尼尔能带与DFT能带示意图

API: get_band_data()
  • get_band_data 函数负责读取能带数据如下:

    dspawpy.io.read.get_band_data(band_dir: str, syst_dir: str | None = None, efermi: float | None = None, zero_to_efermi: bool = False, verbose: bool = False) BandStructureSymmLine

    Reads band structure data from an h5 or json file and constructs a BandStructureSymmLine object.

    参数:
    • band_dir --

      • Path to the band structure file, band.h5 / band.json, or a directory containing band.h5 / band.json

      • Note that wannier.h5 can also be read using this function, but band_dir does not support folder types

    • syst_dir -- Path to system.json, prepared only for auxiliary processing of Wannier data (structure and Fermi level are read from it)

    • efermi -- Fermi level, if the Fermi level in the h5 file is incorrect, it can be specified using this parameter

    • zero_to_efermi -- Whether to shift the Fermi level to 0

    返回类型:

    BandStructureSymmLine

    示例

    >>> from dspawpy.io.read import get_band_data
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.4/band.json')
    

    If you want to process Wannier band structures by specifying wannier.json, you need to additionally specify the syst_dir parameter.

    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.h5')
    >>> band = get_band_data(band_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/wannier.json', syst_dir='dspawpy_proj/dspawpy_tests/inputs/2.30/system.json')
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.5 dos态密度数据处理

如有必要,参考 export_dos.py 将态密度数据提取出来并写入csv文件:

 1# coding:utf-8
 2from dspawpy.io.export import read_dos
 3
 4dos_data = read_dos(
 5    dosfile="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",
 6    mode=1,  # projection mode, only valid for pdos data
 7    hide_index=False,  # hide index column or not
 8    fmt="8.3f",  # decimal format to print
 9)
10dos_data.write_csv("dosdata.csv")

投影模式 mode 可以设置成 1~6 ,分别对应

  1. spdf 轨道

  2. spxpypz... 轨道

  3. 元素

  4. 原子 + spdf 轨道

  5. 原子 + spxpypz... 轨道

  6. 原子 + t2g/eg 分裂轨道

API: read_dos()
dspawpy.io.export.read_dos(dosfile: str | Path, mode: int = 5, hide_index: bool = False, fmt: str = '8.3f') DataFrame

Construct a dataframe of dos data from an h5 or json file.

参数:
  • bandfile (str | Path) -- band data file location, such as 'band.json'.

  • mode (int) -- which projection mode, only valid for pband data.

  • hide_index (bool) -- hide index column in dataframe or not.

  • fmt (str) -- control display decimal, such as '8.3f'

示例

>>> from dspawpy.io.export import read_dos
>>> read_dos(dosfile='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5')
efermi=4.8711625000000005 eV
shape: (401, 3)
┌───────┬──────────┬──────────┐
│ index ┆ energy   ┆ dos      │
╞═══════╪══════════╪══════════╡
│ 1     ┆   -4.830 ┆    0.690 │
│ 2     ┆   -4.780 ┆    0.719 │
│ 3     ┆   -4.730 ┆    0.757 │
│ 4     ┆   -4.680 ┆    0.809 │
│ 5     ┆   -4.630 ┆    0.950 │
│ …     ┆ …        ┆ …        │
│ 397   ┆   14.970 ┆    0.044 │
│ 398   ┆   15.020 ┆    0.041 │
│ 399   ┆   15.070 ┆    0.039 │
│ 400   ┆   15.120 ┆    0.037 │
│ 401   ┆   15.170 ┆    0.035 │
└───────┴──────────┴──────────┘

总的态密度

参考 5dosplot_total.py

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Read projected density of states data
11    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing process
17)
18dos_plotter.add_dos(
19    label="total dos", dos=dos_data
20)  # Set the legend for the density of states plot  # Pass the density of states data
21
22ax = plot_dos(
23    dosplotter=dos_plotter,
24    xlim=[-10, 5],  # Set the energy range
25    ylim=[-15, 15],  # Set the density of states range
26)
27ax.axhline(0, lw=2, ls="-.", color="gray")
28
29filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_total.png"  # File name for the output density of states plot
30os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
31
32fig = ax.get_figure()
33fig.savefig(filename, dpi=300)

知识点:

  1. 使用 get_dos_data 函数可以将DS-PAW计算得到的 dos.h5 文件转化为 pymatgen 支持的格式

  2. 使用 DosPlotter模块获取到DS-PAW计算的 dos.h5 的数据

  3. DosPlotter函数可以传递参数:stack参数表示画态密度是否加阴影, zero_at_efermi 表示是否在态密度图中进行将费米能量置零,这里设置 stack=False , zero_at_efermi=False

  4. 使用 DosPlotter 模块中 add_dos 获取态密度的数据

  5. DosPlotter模块中 get_plot函数 绘制态密度图

执行代码可以得到类似以下态密度图:

_images/5dos_total.png

NiO态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同的轨道上

参考 5dosplot_spd.py

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Read projected DOS data
11    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing is applied
17)
18dos_plotter.add_dos_dict(
19    dos_dict=dos_data.get_spd_dos(),
20    key_sort_func=None,  # Orbital projection  # Specifies the sorting function
21)
22ax = plot_dos(
23    dosplotter=dos_plotter,
24    xlim=[-10, 5],  # Set the energy range
25    ylim=None,  # Set the density of states range
26)
27
28ax.axhline(0, lw=2, ls="-.", color="gray")
29
30filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_spd.png"  # Filename of the output density of states plot
31os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
32
33fig = ax.get_figure()
34fig.savefig(filename, dpi=300)

知识点:

使用 DosPlotter模块中 add_dos_dict 函数 获取投影态密度的数据,之后使用 get_spd_dos 将投影信息按照 spd 轨道投影输出

执行代码可以得到类似以下态密度图:

_images/5dos_spd.png

NiO轨道投影态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同的元素上

参考 5dosplot_elt.py

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Reads projected DOS data
11    return_dos=False,  # If False, always returns a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing is applied
17)
18dos_plotter.add_dos_dict(
19    dos_dict=dos_data.get_element_dos(),
20    key_sort_func=None,  # Projected DOS for elements  # Specify the sorting function
21)
22
23ax = plot_dos(
24    dosplotter=dos_plotter,
25    xlim=[-10, 5],  # Set the energy range
26    ylim=None,  # Set the density of states range
27)
28ax.axhline(0, lw=2, ls="-.", color="gray")
29
30filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_elt.png"  # Filename for the output density of states plot
31os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
32
33fig = ax.get_figure()
34fig.savefig(filename, dpi=300)

知识点:

使用 DosPlotter模块中 add_dos_dict 函数 获取投影态密度的数据,之后使用 get_element_dos 将投影信息按照不同元素投影输出

执行代码可以得到类似以下态密度图:

_images/5dos_elt.png

NiO元素投影态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同原子的不同轨道上

参考 5dosplot_atom_orbit.py

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.core import Orbital
 5from pymatgen.electronic_structure.plotter import DosPlotter
 6
 7from dspawpy.io.read import get_dos_data
 8from dspawpy.plot import plot_dos
 9
10dos_data = get_dos_data(
11    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Reads projected density of states data
12    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
13)
14dos_plotter = DosPlotter(
15    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
16    stack=False,  # True indicates drawing an area plot
17    sigma=None,  # Gaussian broadening, None indicates no smoothing treatment
18)
19
20# ! Specify atomic number and orbital
21dict_index_orbit = {0: ["dxy"], 2: ["s"]}
22
23print("Plotting...")
24for index in dict_index_orbit:
25    _os = dict_index_orbit[index]
26    _e = str(dos_data.structure.sites[index].species)
27    for _orb in _os:
28        dos_plotter.add_dos(
29            f"{_e}(atom-{index}) {_orb}",  # label
30            dos_data.get_site_orbital_dos(
31                dos_data.structure[index],
32                getattr(Orbital, _orb),
33            ),
34        )
35
36ax = plot_dos(
37    dosplotter=dos_plotter,
38    xlim=[-10, 5],  # Set the energy range
39    ylim=None,  # Set the density of states range
40)
41ax.axhline(0, lw=2, ls="-.", color="gray")
42
43figname = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_atom_orbit.png"  # Output density of states figure filename
44os.makedirs(os.path.dirname(os.path.abspath(figname)), exist_ok=True)
45
46fig = ax.get_figure()
47fig.savefig(figname, dpi=300)

知识点:

  1. 使用 get_site_orbital_dos函数提取dos数据中特定原子特定轨道的贡献,dos_data.structure[0],Orbital(4) 表示获取第1个原子的dxy轨道的态密度,get_site_orbital_dos函数中序号从0开始

  2. 运行此脚本,根据提示选择元素和轨道,可以得到相应的态密度图

执行代码可以得到类似以下态密度图:

_images/5dos_atom_orbit.png

NiO原子轨道态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将态密度投影到不同原子的分裂d轨道(t2g, eg)上

参考 5dosplot_t2g_eg.py

 1# coding:utf-8
 2import os
 3
 4from pymatgen.electronic_structure.plotter import DosPlotter
 5
 6from dspawpy.io.read import get_dos_data
 7from dspawpy.plot import plot_dos
 8
 9dos_data = get_dos_data(
10    dos_dir="dspawpy_proj/dspawpy_tests/inputs/3.2.4/dos.h5",  # Read projected density of states data
11    return_dos=False,  # If False, always returns a CompleteDos object (regardless of whether projection was enabled during calculation)
12)
13dos_plotter = DosPlotter(
14    zero_at_efermi=True,  # Whether to set the Fermi level as the zero point
15    stack=False,  # True indicates drawing an area chart
16    sigma=None,  # Gaussian broadening, None indicates no smoothing is applied
17)
18# print(dos_data.structure)
19
20# Specify the atomic number, starting from 0
21ais = [1]
22
23print("Plotting...")
24atom_indices = [int(ai) for ai in ais]
25for atom_index in atom_indices:
26    dos_plotter.add_dos_dict(
27        dos_data.get_site_t2g_eg_resolved_dos(dos_data.structure[atom_index]),
28    )
29
30ax = plot_dos(
31    dosplotter=dos_plotter,
32    xlim=[-10, 5],  # Set the energy range
33    ylim=None,  # Set the density of states range
34)
35ax.axhline(0, lw=2, ls="-.", color="gray")
36
37filename = "dspawpy_proj/dspawpy_tests/outputs/us/5dos_t2g_eg.png"  # Output density of states plot filename
38os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
39
40fig = ax.get_figure()
41fig.savefig(filename, dpi=300)

知识点:

  1. 使用 get_site_t2g_eg_resolved_dos函数 提取dos数据中特定原子的 t2g和 eg轨道的贡献,这是获取第2个原子的t2g和eg轨道的贡献

  2. 运行此脚本,根据提示选择原子序号,可以得到相应的态密度图

执行代码可以得到类似以下态密度图:

_images/5dos_t2g_eg.png

NiO分裂d轨道原子投影态密度示意图

知识点:

如果元素不含d轨道,会画成空白图片

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

d-带中心分析

以 Pb-slab 体系为例,对 Pt 原子进行 d-band 中心分析:

参考 5center_dband.py

 1# coding:utf-8
 2from dspawpy.io.read import get_dos_data
 3from dspawpy.io.utils import d_band
 4
 5dos_data = get_dos_data(
 6    dos_dir="dspawpy_proj/dspawpy_tests/inputs/supplement/dos.h5",  # Read projected density of states data
 7    return_dos=False,  # If False, always returns a CompleteDos object (regardless of whether projection was enabled during calculation)
 8)
 9for spin in dos_data.densities:
10    print("spin=", spin)
11    c = d_band(spin, dos_data)
12    print(c)

执行代码可以得到类似以下结果:

spin=1
-1.785319344084034

备注

目前仅支持全部原子平均的 d 轨道中心,不支持元素、原子投影或其他轨道,也不支持选择自旋方向或能量范围。

get_dos_data 函数负责处理态密度数据:

API: get_dos_data()
dspawpy.io.read.get_dos_data(dos_dir: str, return_dos: bool = False, verbose: bool = False)

Read density of states (DOS) data from an h5 or json file, and construct a CompleteDos or DOS object

参数:
  • dos_dir -- Path to the density of states file, dos.h5 / dos.json, or a folder containing dos.h5 / dos.json

  • return_dos (bool, optional) -- Whether to return the DOS object. If False, a CompleteDos object is returned uniformly (regardless of whether projection was enabled during calculation)

返回类型:

CompleteDos or Dos

示例

>>> from dspawpy.io.read import get_dos_data
>>> dos = get_dos_data(dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5')
>>> dos = get_dos_data(dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5', return_dos=True)

8.6 bandDos能带和态密度共同显示

以应用教程中Si体系为例:

将能带和态密度显示在一张图上

参考 6bandDosplot.py

 1# coding:utf-8
 2import os
 3
 4import numpy as np
 5from matplotlib.axes import Axes
 6from pymatgen.electronic_structure.plotter import BSDOSPlotter
 7
 8from dspawpy.io.read import get_band_data, get_dos_data
 9
10bandfile = "dspawpy_proj/dspawpy_tests/inputs/2.3/band.h5"  # Normal band data
11band_data = get_band_data(
12    band_dir=bandfile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
14    efermi=None,  # Used for manually correcting the Fermi level
15)
16band_efermi = band_data.efermi
17dosfile = "dspawpy_proj/dspawpy_tests/inputs/2.5/dos.h5"  # Density of states data
18dos_data = get_dos_data(
19    dos_dir=dosfile,
20    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
21)
22dos_efermi = dos_data.efermi
23bdp = BSDOSPlotter(
24    bs_projection=None,  # Band structure projection method, None means no projection
25    dos_projection=None,  # Projection method for density of states, None means no projection
26    vb_energy_range=4,  # Valence band energy range
27    cb_energy_range=4,  # Conduction band energy range
28    fixed_cb_energy=False,  # Whether to fix the conduction band energy range
29    egrid_interval=1,  # Energy grid interval
30    font="DejaVu Sans",  # Default is Times New Roman, change to DejaVu Sans to avoid warnings due to missing font on Linux
31    axis_fontsize=20,  # Axis font size
32    tick_fontsize=15,  # Tick label font size
33    legend_fontsize=14,  # Legend font size
34    bs_legend="best",  # Band structure legend position
35    dos_legend="best",  # Density of States legend position
36    rgb_legend=True,  # Use colored legend
37    fig_size=(11, 8.5),  # Figure size
38)
39if band_efermi != dos_efermi:
40    print(f"{band_efermi=:.4f} eV")
41    print(f"{dos_efermi=:.4f} eV")
42    d_efermi = band_efermi - dos_efermi
43
44    print(
45        "! Band and DOS Fermi levels are inconsistent, using DOS Fermi level as reference"
46    )
47    band_data.bands = {spin: v + d_efermi for spin, v in band_data.bands.items()}
48
49    # ! Band and DOS Fermi levels are inconsistent, using Band level as the reference
50    # dos_data.energies -= d_efermi
51
52axes_or_plt = bdp.get_plot(
53    bs=band_data, dos=dos_data
54)  # Pass band data  # Pass density of states data
55
56if isinstance(axes_or_plt, Axes):
57    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
58elif np.iterable(axes_or_plt):
59    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
60else:
61    fig = axes_or_plt.gcf()  # older version pymatgen
62
63filename = "dspawpy_proj/dspawpy_tests/outputs/us/6bandDos.png"  # Filename for the band structure - density of states plot output
64os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
65fig.savefig(filename, dpi=300)
66print("==> Saved", filename)

执行代码可以得到类似以下能带态密度图:

_images/6bandDos.png

单晶硅能带-态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

将能带和投影态密度显示在一张图上

参考 6bandPdosplot.py

 1# coding:utf-8
 2import os
 3
 4import numpy as np
 5from matplotlib.axes import Axes
 6from pymatgen.electronic_structure.plotter import BSDOSPlotter
 7
 8from dspawpy.io.read import get_band_data, get_dos_data
 9
10bandfile = "dspawpy_proj/dspawpy_tests/inputs/2.4/band.h5"  # Normal band data
11band_data = get_band_data(
12    band_dir=bandfile,
13    syst_dir=None,  # path to system.json file, required only when band_dir is a json file
14    efermi=None,  # Used for manually correcting the Fermi level
15)
16band_efermi = band_data.efermi
17dosfile = (
18    "dspawpy_proj/dspawpy_tests/inputs/2.6/dos.h5"  # DOS data for projected states
19)
20dos_data = get_dos_data(
21    dos_dir=dosfile,
22    return_dos=False,  # If False, always return a CompleteDos object (regardless of whether projection was enabled during calculation)
23)
24dos_efermi = dos_data.efermi
25bdp = BSDOSPlotter(
26    bs_projection="elements",  # Projection method for band structure, None means no projection
27    dos_projection="elements",  # Project DOS onto elements
28    vb_energy_range=4,  # Valence band energy range
29    cb_energy_range=4,  # Conduction band energy range
30    fixed_cb_energy=False,  # Whether to fix the conduction band energy range
31    egrid_interval=1,  # Energy grid interval
32    font="DejaVu Sans",  # Default is Times New Roman, can be changed to DejaVu Sans to avoid warnings due to font not being installed on Linux
33    axis_fontsize=20,  # Axis font size
34    tick_fontsize=15,  # Tick label font size
35    legend_fontsize=14,  # Legend font size
36    bs_legend="best",  # Band structure legend position
37    dos_legend="best",  # Position of the projected density of states legend
38    rgb_legend=True,  # Use colored legend
39    fig_size=(11, 8.5),  # Figure size
40)
41if band_efermi != dos_efermi:
42    print(f"{band_efermi=:.4f} eV")
43    print(f"{dos_efermi=:.4f} eV")
44    d_efermi = band_efermi - dos_efermi
45
46    print(
47        "! Band and DOS Fermi levels are inconsistent, using DOS Fermi level as reference"
48    )
49    band_data.bands = {spin: v + d_efermi for spin, v in band_data.bands.items()}
50
51    # ! Band and DOS Fermi levels are inconsistent, using Band level as reference
52    # dos_data.energies -= d_efermi
53
54axes_or_plt = bdp.get_plot(
55    bs=band_data,
56    dos=dos_data,
57)  # Pass band structure data  # Pass projected density of states data
58
59if isinstance(axes_or_plt, Axes):
60    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
61elif np.iterable(axes_or_plt):
62    fig = np.asarray(axes_or_plt).flatten()[0].get_figure()
63else:
64    fig = axes_or_plt.gcf()  # older version pymatgen
65
66filename = "dspawpy_proj/dspawpy_tests/outputs/us/6bandPdos.png"  # filename for the band structure-projected density of states plot
67os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
68fig.savefig(filename, dpi=300)
69print("==> Saved", filename)

执行代码可以得到类似以下能带态密度图:

_images/6bandPdos.png

单晶硅能带-投影态密度示意图

警告

  1. 给定投影能带数据,默认将沿着元素投影;给定普通能带数据(或体系所含元素种类超过4种),则不投影,并输出警告

  2. 给定投影态密度数据,默认也将沿着元素投影,可以换成沿着轨道投影,或者不投影;给定普通态密度数据且未关闭态密度投影选项 BSDOSPlotter(dos_projection=None),pymatgen绘图程序将报错,这就是上面特意准备了一个 6bandDosplot.py 文件的原因。

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.7 optical光学性质数据处理

以快速入门Si体系光学性质计算得到的 scf.h5 为例(注:输出文件名与task一致,task = scf,io.optical = true可计算光学性质):

反射率数据处理,参考 7optical.py

 1# coding:utf-8
 2from dspawpy.plot import plot_optical
 3
 4plot_optical(
 5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.12/scf.h5",
 6    keys=["ExtinctionCoefficient", "Reflectance"],
 7    axes=["X"],  # ["X", "Y", "Z", "XY", "YZ", "ZX"]
 8    prefix="dspawpy_proj/dspawpy_tests/outputs/optical",  # Where to save, if empty, it means the current folder
 9    save=True,  # Whether to save the image with the tool's name, if False, please refer to the script below to save manually
10)
11
12# The above function will plot and save the images of ExtinctionCoefficient and Reflectance separately
13# To plot multiple properties on the same figure, uncomment the following code and set the save parameter above to False
14
15# import os
16# import matplotlib.pyplot as plt
17#
18# plt.tick_params(labelsize=16)
19# plt.tight_layout()
20# filename = "outputs/us/7optical.png"  # Filename for the output optical properties plot
21# os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
22# plt.savefig(filename, dpi=300)

知识点:

Reflectance为光学性质中的一种,用户可以根据自己的需求将该关键词修改为“AbsorptionCoefficient”或”ExtinctionCoefficient”或”RefractiveIndex”,分别对应吸收系数、消光系数和折射率

执行代码可以得到类似以下反射率随能量变化的曲线:

_images/7optical.png

单晶硅Reflectance随光子能量变化趋势示意图

API: plot_optical()
dspawpy.plot.plot_optical(datafile: str = 'optical.h5', keys: List[str] = ['AbsorptionCoefficient', 'ExtinctionCoefficient', 'RefractiveIndex', 'Reflectance'], axes: List[str] = ['X', 'Y', 'Z', 'XY', 'YZ', 'ZX'], raw: bool = False, prefix: str = '', save: bool = True, verbose: bool = False)

After the optical property calculation task is completed, read the data and draw a preview image

optical.h5/optical.json -> optical.png

参数:
  • datafile -- Path to an h5 or json file, or a folder containing any of these files, default 'optical.h5'

  • keys -- One of "AbsorptionCoefficient", "ExtinctionCoefficient", "RefractiveIndex", "Reflectance", default "AbsorptionCoefficient"

  • axes -- Index, default "X", "Y", "Z", "XY", "YZ", "ZX"

  • raw -- Whether to save plot data to CSV

  • prefix -- Folder path to save images, if empty, saves in the current directory

  • save -- Whether to save the image, default is True

示例

Plot and save the plot data to rawoptical.csv

>>> from dspawpy.plot import plot_optical
>>> plot_optical("dspawpy_proj/dspawpy_tests/inputs/2.12/scf.h5", "AbsorptionCoefficient", ['X', 'Y'], prefix='dspawpy_proj/dspawpy_tests/outputs/doctest')
>>> plot_optical("dspawpy_proj/dspawpy_tests/inputs/2.12/optical.json", ["AbsorptionCoefficient"], ['X', 'Y'], prefix='dspawpy_proj/dspawpy_tests/outputs/doctest', raw=True)

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.8 neb过渡态计算数据处理

以快速入门 H 在 Pt(100) 表面扩散为例进行介绍:

输入文件之生成中间构型

  • 参考 8neb_interpolate_structures.py

     1# coding:utf-8
     2from dspawpy.diffusion.neb import NEB, write_neb_structures
     3from dspawpy.diffusion.nebtools import write_json_chain
     4from dspawpy.io.structure import read
     5
     6# Read initial configuration
     7init_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/00/structure00.as")[0]
     8# Read final state configuration
     9final_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/04/structure04.as")[0]
    10
    11neb = NEB(
    12    initial_structure=init_struct,  # Initial structure
    13    final_structure=final_struct,  # Final state configuration
    14    nimages=8,  # Total of 8 configurations, including initial and final states
    15)
    16structures = neb.linear_interpolate()  # Linear interpolation
    17# structures = neb.idpp_interpolate()   # IDPP interpolation
    18
    19# Save as structure file to dest path
    20write_neb_structures(
    21    structures=structures,  # Insert interpolated structure chains
    22    coords_are_cartesian=True,  # Whether to save in Cartesian coordinates
    23    fmt="as",  # Save format, supported formats: 'json', 'as', 'hzw', 'pdb', 'xyz', 'dump'
    24    path="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures",  # Save path
    25    prefix="structure",  # File name prefix
    26)
    27
    28# Preview initial structure chain
    29write_json_chain(
    30    preview=True,  # whether to enable preview mode
    31    directory="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures",  # Directory for NEB calculations
    32    step=-1,  # Default to saving the structure chain of the last ion step (latest)
    33    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Save path
    34)
    35# write_xyz_chain(preview=True, # Whether to run in preview mode
    36#                  directory="dspawpy_proj/dspawpy_tests/outputs/us/8neb_interpolate_structures", # NEB calculation directory
    37#                  step=-1, # Default to saving the structure chain of the last ionic step (latest)
    38#                  dst='dspawpy_proj/dspawpy_tests/outputs/us/8neb' # save path
    39# )
    

知识点:

  1. 用户可以根据需要自行修改插点个数,设置为8得到包含8个结构文件的文件夹,其中中间构型为6个

  2. neb.linear_interpolate为线性插值方法,pbc参数为 True 时将锁定寻找最短扩散路径,默认为 False 以增加用户控制的灵活性,这是因为

  3. 举个例子,初态某原子的分数坐标是 0.2,终态变成 0.8。pbc = True 将强制设置扩散路径为 0.2 -> -0.2。pbc = False 则用户可以令程序按照 0.2 -> 0.8 的扩散路径进行插值;如果要用最短路径,手动将 0.8 改为 -0.2 即可,从而确保程序按照使用者的意图完成插值初猜。

绘制能垒图

neb.iniFin = true/false

当设置 neb.iniFin = true/false 时,都可使用读取neb计算的路径进行势垒分析(确保初末态计算文件在neb计算路径下):

  • 参考 8neb_barrier_CubicSpline.py

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import plot_barrier
     3
     4directory_of_neb_task = (
     5    "dspawpy_proj/dspawpy_tests/inputs/2.15"  # <-- Please modify to the actual NEB path
     6)
     7
     8# Plotting the energy barrier using CubicSpline interpolation
     9plot_barrier(
    10    directory=directory_of_neb_task,  # path of the neb task
    11    method="CubicSpline",  # Cubic spline interpolation
    12    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_CubicSpline.png",  # Output filename for the energy barrier plot
    13    show=False,  # Whether to display the energy barrier plot
    14)
    

备注

运行上述脚本后,可得到类似以下三次样条插值的势垒曲线:

_images/neb-barrier_cs.png

对于这个算例,三次样条插值后,曲线会出现不合理的“下坠”区域,这是三次样条插值算法的特性所决定的。

dspawpy 内部调用 scipy 的插值算法 ,上面这个脚本我们以三次样条插值算法为例,它在 scipy 文档中的定义为:

class scipy.interpolate.CubicSpline(x, y, axis=0, bc_type='not-a-knot', extrapolate=None)

关键词参数包括 axis, bc_type, extrapolate,具体含义见 scipy.interpolate.CubicSpline 。我们可以往 plot_barrier 函数中指定相应的关键词参数(axis, bc_type, extrapolate),将其传递给 scipy.interpolate.CubicSpline 这个类处理。

下面我们采用 8neb_barrier.py 脚本,对比三种算法插值绘制出的曲线:

 1# coding:utf-8
 2import os
 3
 4import matplotlib.pyplot as plt
 5
 6from dspawpy.diffusion.nebtools import plot_barrier
 7
 8# Compare the differences in energy barrier curves drawn by different interpolation methods, where show should be set to False
 9# 1. interp1d
10plot_barrier(
11    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # path for NEB calculation
12    ri=None,  # Reaction coordinate between the initial structure and the second structure, required when the NEB task only calculated intermediate structures
13    rf=None,  # Reaction coordinate between the last configuration and the second-to-last configuration, when the NEB task only calculated intermediate configurations
14    ei=None,  # Energy of the initial configuration, required when the NEB task only calculated intermediate configurations
15    ef=None,  # Energy of the final configuration, required when the NEB task only calculated intermediate configurations
16    method="interp1d",  # Interpolation method
17    figname=None,  # Name of the output energy barrier plot file
18    show=False,  # Whether to display the energy barrier plot
19    kind="quadratic",  # Parameter of the interpolation method
20)
21# 2. CubicSpline
22plot_barrier(
23    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
24    method="CubicSpline",
25    figname=None,
26    show=False,
27)
28# 3. pchip
29plot_barrier(
30    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
31    method="pchip",
32    figname=None,
33    show=False,
34)
35
36filename = "dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_comparison.png"  # Filename for the energy barrier plot output
37os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
38plt.savefig(filename, dpi=300)
39# plt.show()
_images/neb-barrier.png

知识点:

  1. 选择合适的插值算法对于优化最终曲线的呈现效果至关重要

  2. 多数情况下,选择 pchip 这种单调三次样条插值算法即可达到较好效果,这也是默认调用的插值算法

neb.iniFin = true

当设置 neb.iniFin = true 时,读取neb计算所得的 neb.h5/neb.json 文件可快速进行势垒分析:

  • 参考 8neb_barrier_CubicSpline.py

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import plot_barrier
     3
     4# Plot energy barrier using CubicSpline interpolation
     5plot_barrier(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.15/neb.h5",  # Path to neb.h5
     7    method="CubicSpline",  # Cubic spline interpolation
     8    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb_barrier_.png",  # Output file name for the energy barrier plot
     9    show=False,  # Whether to display the energy barrier plot
    10)
    

处理得到的势垒图与之前读取路径效果一致。

备注

  1. neb.h5 和 neb.json文件所存能量为TotalEnergy,如需得精确的势垒值,建议采用读取neb计算路径的方法进行处理(取TotalEnergy0)

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

过渡态计算数据处理

NEB计算完成后,一般要画出能垒图观察,并检查各插值构型最终的受力大小,从而确保受力小于指定的阈值。如果结果异常,还需要检查各插值构型在结构优化过程中的受力与能量变化趋势,判断是否真正“收敛”。上述这些操作至少需要三次循环,为简化操作,我们提供了一个一步到位的总结函数 summary

  • 参考 8neb_check_results.py

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import summary
     3
     4# Import the neb calculation directory, a complete folder after neb calculation needs to be provided
     5summary(
     6    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",
     7    show_converge=False,  # Whether to display the convergence plots of energy and force
     8    outdir="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Path to save convergence plots of energy and forces
     9    figname="dspawpy_proj/dspawpy_tests/outputs/us/8neb/neb_barrier_summary.png",  # Path to save the energy barrier plot
    10)
    11# Additional keyword arguments can be set for plotting the barrier diagram, such as:
    12# summary(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='CubicSpline') # Change to CubicSpline for spline interpolation
    

    知识点:

    1. 此脚本将以表格形式打印各构型的能量和受力、绘制能垒图,并绘制中间构型的能量与受力收敛过程图

    2. neb.iniFin = false ,用户必须将自洽计算的结果文件 scf.h5system.json 文件复制到对应的初末态子文件夹中,否则程序无法读取初末态能量和受力信息,将报错退出

    3. 默认情况下,能垒图存储在neb计算目录外层,各中间构型的能量与受力收敛图存储在各子文件夹

    执行代码可以得到类似如下NEB计算各构型的能量和受力表格:

    Image

    Force (eV/Å)

    Reaction coordinate (Å)

    Energy (eV)

    Delta energy (eV)

    00

    0.1803

    0.0000

    -39637.0984

    0.0000

    01

    0.0263

    0.5428

    -39637.0186

    0.0798

    02

    0.0248

    1.0868

    -39636.8801

    0.2183

    03

    0.2344

    1.5884

    -39636.9984

    0.1000

    04

    0.0141

    2.0892

    -39637.0900

    0.0084

    除了可以获得能垒图外,还可以得到各中间构型的能量和受力收敛曲线(以02构型为例)

    _images/neb-energy.png

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

观察NEB链

此处所说NEB链指的是各插值构型(structure00.as, structure01.as, ...)之间的几何关系,而不是单个构型在优化过程中的变化。

  • NEB任务计算量较大,观察NEB链有助于判断NEB计算的收敛速度。另外,通过插值算法生成中间结构后,经常需要预览NEB链。这些需求可以通过 8neb_visualize.py 脚本实现:

 1# coding:utf-8
 2from dspawpy.diffusion.nebtools import write_json_chain, write_xyz_chain
 3
 4# Convert the configuration chain under the NEB calculation path to a JSON format file
 5write_json_chain(
 6    preview=False,  # If the NEB calculation is already completed, preview mode is not required
 7    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # NEB calculation directory
 8    step=-1,  # Default to saving the configuration chain of the last ion step (latest)
 9    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Save path
10    ignorels=False,  # Set to True to ignore latestStructureXX.as files
11)
12
13# Convert the configuration chain in the NEB calculation path to xyz format files
14write_xyz_chain(
15    preview=False,  # If the NEB calculation is already completed, preview mode is not required
16    directory="dspawpy_proj/dspawpy_tests/inputs/2.15",  # NEB calculation directory
17    step=-1,  # Default to saving the configuration chain of the last ionic step (latest)
18    dst="dspawpy_proj/dspawpy_tests/outputs/us/8neb",  # Save path
19    ignorels=False,  # Set to True to ignore latestStructureXX.as files
20)

知识点:

  1. 此脚本生成neb_movie*.json文件后,通过 Device Studio --> Simulator --> DS-PAW --> Analysis Plot 打开 json 文件即可观察

  2. directory指定为NEB计算主路径,需提供neb计算完成后的完整文件夹

  3. 该脚本支持处理正在进行中的(即未完成的)neb计算文件,方便用户监测实时轨迹

  4. xyz文件可通过 OVITO 软件打开查看:通过 Device Studio --> Simulator --> OVITO 打开可视化界面,将xyz文件拖入即可

  5. 结构信息读取优先级:latestStructureXX.as > h5 > json;设置ignorels为True后,先尝试读取 h5 中的数据,失败则读取 json 中的数据

计算构型间距

  • 参考这个脚本 8calc_dist.py

     1# coding:utf-8
     2from dspawpy.diffusion.nebtools import get_distance
     3from dspawpy.io.structure import read
     4
     5# Please modify the paths of structure01.as and structure02.as structure files according to the actual situation
     6# First read the fractional coordinates, element list, and cell information of the two configurations
     7s1 = read("dspawpy_proj/dspawpy_tests/inputs/2.15/01/structure01.as")[0]
     8s2 = read("dspawpy_proj/dspawpy_tests/inputs/2.15/02/structure02.as")[0]
     9# Calculate the distance between the two configurations, note that this function only accepts fractional coordinates
    10dist = get_distance(
    11    spo1=s1.frac_coords,
    12    spo2=s2.frac_coords,
    13    lat1=s1.lattice.matrix,
    14    lat2=s2.lattice.matrix,
    15)
    16print("The distance between the two configurations is:", dist, "Angstrom")
    

neb续算

  • 如果需对neb进行续算,可参考 8neb_restart.py

     1# coding:utf-8
     2import os
     3from shutil import copytree, rmtree
     4
     5from dspawpy.diffusion.nebtools import restart
     6
     7if os.path.isdir("dspawpy_proj/dspawpy_tests/outputs/us/neb4bk"):
     8    rmtree("dspawpy_proj/dspawpy_tests/outputs/us/neb4bk")
     9
    10copytree(
    11    "dspawpy_proj/dspawpy_tests/inputs/2.15",
    12    "dspawpy_proj/dspawpy_tests/outputs/us/neb4bk",
    13)
    14restart(
    15    directory="dspawpy_proj/dspawpy_tests/outputs/us/neb4bk",  # NEB task path
    16    output="dspawpy_proj/dspawpy_tests/outputs/us/8neb_restart",  # Backup destination
    17)
    

    具体效果见 neb过渡态计算续算说明

neb计算过程中能量和最大原子受力的变化趋势图

  • 要查看neb计算过程中能量和最大原子受力的变化趋势图,可参考 8neb_energy_force_curves.py

    1# coding:utf-8
    2from dspawpy.diffusion.nebtools import monitor_force_energy
    3
    4# Specify the path to the NEB calculation folder; after running, Energies.png and MaxForce.png images will be generated in the specified directory
    5unfinished_neb_folder = "dspawpy_proj/dspawpy_tests/inputs/supplement/neb_unfinished"
    6monitor_force_energy(
    7    directory=unfinished_neb_folder,
    8    outdir="imgs",  # Output image path
    9)
    

    将生成能量和受力变化趋势图:

    _images/Energies.png
    _images/MaxForce.png
API: write_neb_structures(), plot_barrier(), summary(), get_distance(), write_movie_json(), write_xyz(), restart()
  • write_neb_structures 函数负责生成中间构型:

    dspawpy.diffusion.neb.write_neb_structures(structures: list, coords_are_cartesian: bool = True, fmt: str = 'as', path: str = '.', prefix='structure')

    Interpolate and generate intermediate configuration files

    参数:
    • structures -- Structure list

    • coords_are_cartesian -- Is the coordinate Cartesian

    • fmt -- Structure file type, default to "as"

    • path -- Save path

    • prefix -- Filename prefix, default to "structure", which will generate files like structure00.as, structure01.as, ...

    返回:

    Saves the configuration file

    返回类型:

    file

    示例

    First, read the .as file to create a structure object

    >>> from dspawpy.io.structure import read
    >>> init_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/00/structure00.as")[0]
    >>> final_struct = read("dspawpy_proj/dspawpy_tests/inputs/2.15/04/structure04.as")[0]
    

    Then, interpolate and generate intermediate structure files

    >>> from dspawpy.diffusion.neb import NEB,write_neb_structures
    >>> neb = NEB(init_struct,final_struct,8)
    >>> structures = neb.linear_interpolate()   # Linear interpolation
    

    Interpolated structures can be saved to the neb folder.

    >>> write_neb_structures(structures, path="dspawpy_proj/dspawpy_tests/outputs/doctest/11neb_interpolate_structures")
    ==> ...structure00.as...
    ==> ...structure01.as...
    ==> ...structure02.as...
    ==> ...structure03.as...
    ==> ...structure04.as...
    ==> ...structure05.as...
    ==> ...structure06.as...
    ==> ...structure07.as...
    
  • plot_barrier 函数负责绘制能垒图:

    dspawpy.diffusion.nebtools.plot_barrier(datafile: str = 'neb.h5', directory: str | None = None, ri: float | None = None, rf: float | None = None, ei: float | None = None, ef: float | None = None, method: str = 'PchipInterpolator', figname: str | None = 'neb_barrier.png', show: bool = True, raw: bool = False, verbose: bool = False, **kwargs)

    Call the scipy.interpolate interpolation algorithm to fit the NEB barrier and plot

    参数:
    • datafile -- Path to neb.h5 or neb.json file

    • directory -- NEB calculation path

    • ri -- Initial reaction coordinate

    • rf -- Final state reaction coordinate

    • ei -- Initial state self-consistent energy

    • ef -- Final state self-consistent energy

    • method (str, optional) -- Interpolation algorithm, default 'PchipInterpolator'

    • figname (str, optional) -- Barrier image name, default 'neb_barrier.png'

    • show (bool, optional) -- Whether to display the interactive interface, default True

    • raw (bool, optional) -- Whether to return plotting data to CSV

    抛出:
    • ImportError -- The specified interpolation algorithm does not exist in scipy.interpolate

    • ValueError -- The parameters passed to the interpolation algorithm do not meet the requirements of the algorithm

    示例

    >>> from dspawpy.diffusion.nebtools import plot_barrier
    >>> import matplotlib.pyplot as plt
    

    Comparing different interpolation algorithms

    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='interp1d', kind=2, figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='interp1d', kind=3, figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='CubicSpline', figname=None, show=False)
    >>> plot_barrier(directory='dspawpy_proj/dspawpy_tests/inputs/2.15', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_comparison.png', show=False)
    ==> ...barrier_comparison.png...
    

    Attempt to read neb.h5 file or neb.json file

    >>> plot_barrier(datafile='dspawpy_proj/dspawpy_tests/inputs/2.15/neb.h5', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_h5.png', show=False)
    ==> ...barrier_h5.png
    >>> plot_barrier(datafile='dspawpy_proj/dspawpy_tests/inputs/2.15/neb.json', method='pchip', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/barrier_json.png', show=False)
    ==> ...barrier_json.png...
    
  • summary 函数负责总结NEB计算任务的说明文档:

    dspawpy.diffusion.nebtools.summary(directory: str = '.', raw=False, show_converge=False, outdir: str | None = None, **kwargs)

    Summary of NEB task completion, execute the following steps in order:

      1. Print the forces, reaction coordinates, energy, and energy differences from the initial configuration for each structure

      1. Plot the energy barrier diagram

      1. Plot and save the convergence processes of energy and forces during the structure optimization

    参数:
    • directory -- NEB path, default to the current path

    • raw -- Whether to save the plot data to a CSV file

    • show_converge -- Whether to display energy and force convergence plots of the structural optimization process, default is not displayed

    • outdir -- Path to save the convergence process figure, default to directory

    • **kwargs (dict) -- Parameters passed to plot_barrier

    示例

    >>> from dspawpy.diffusion.nebtools import summary
    >>> directory = 'dspawpy_proj/dspawpy_tests/inputs/2.15' # Path for NEB calculation, default to current path
    >>> summary(directory, show=False, figname='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_barrier.png')
    shape: (5, 5)
    ┌────────────┬─────────────┬──────────┬───────────────┬──────────┐
    │ FolderName ┆ Force(eV/Å) ┆ RC(Å)    ┆ Energy(eV)    ┆ E-E0(eV) │
    ╞════════════╪═════════════╪══════════╪═══════════════╪══════════╡
    │ 00         ┆ 0.180272    ┆ 0.0      ┆ -39637.097656 ┆ 0.0      │
    │ 01         ┆ 0.014094    ┆ 0.542789 ┆ -39637.019531 ┆ 0.079814 │
    │ 02         ┆ 0.026337    ┆ 1.0868   ┆ -39636.878906 ┆ 0.218265 │
    │ 03         ┆ 0.024798    ┆ 1.588367 ┆ -39637.0      ┆ 0.100043 │
    │ 04         ┆ 0.234429    ┆ 2.089212 ┆ -39637.089844 ┆ 0.008414 │
    └────────────┴─────────────┴──────────┴───────────────┴──────────┘
    ==> ...neb_barrier.png...
    ==> ...converge.png...
    ==> ...converge.png...
    ==> ...converge.png...
    
    >>> summary(directory, show=False, figname='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_barrier.png', outdir="dspawpy_proj/dspawpy_tests/outputs/doctest/neb_summary")
    shape: (5, 5)
    ┌────────────┬─────────────┬──────────┬───────────────┬──────────┐
    │ FolderName ┆ Force(eV/Å) ┆ RC(Å)    ┆ Energy(eV)    ┆ E-E0(eV) │
    ╞════════════╪═════════════╪══════════╪═══════════════╪══════════╡
    │ 00         ┆ 0.180272    ┆ 0.0      ┆ -39637.097656 ┆ 0.0      │
    │ 01         ┆ 0.014094    ┆ 0.542789 ┆ -39637.019531 ┆ 0.079814 │
    │ 02         ┆ 0.026337    ┆ 1.0868   ┆ -39636.878906 ┆ 0.218265 │
    │ 03         ┆ 0.024798    ┆ 1.588367 ┆ -39637.0      ┆ 0.100043 │
    │ 04         ┆ 0.234429    ┆ 2.089212 ┆ -39637.089844 ┆ 0.008414 │
    └────────────┴─────────────┴──────────┴───────────────┴──────────┘
    ==> ...neb_barrier.png...
    ==> ...converge.png...
    ==> ...converge.png...
    ==> ...converge.png...
    

    If inifin=False, the user must place a converged scf.h5 or system.json in the initial and final state subfolders.

  • get_distance 函数可以计算两个构型间的距离:

    dspawpy.diffusion.nebtools.get_distance(spo1, spo2, lat1, lat2)

    Calculate the distance between two structures based on their fractional coordinates and cell parameters

    参数:
    • spo1 (np.ndarray) -- Scores coordinate list 1

    • spo2 (np.ndarray) -- Fractional coordinate list 2

    • lat1 (np.ndarray) -- Cell 1

    • lat2 (np.ndarray) -- Cell 2

    返回:

    Distance

    返回类型:

    float

    示例

    First, read the structure information

    >>> from dspawpy.io.structure import read
    >>> s1 = read('dspawpy_proj/dspawpy_tests/inputs/2.15/01/structure01.as')[0]
    >>> s2 = read('dspawpy_proj/dspawpy_tests/inputs/2.15/02/structure02.as')[0]
    

    Calculate the distance between two configurations

    >>> from dspawpy.diffusion.nebtools import get_distance
    >>> dist = get_distance(s1.frac_coords, s2.frac_coords, s1.lattice.matrix, s2.lattice.matrix)
    >>> print('The distance between the two configurations is:', dist, 'Angstrom')
    The distance between the two configurations is: 0.476972808803491 Angstrom
    
  • write_movie_jsonwrite_xyz 函数可以将中间构型写入json或者xyz文件:

  • restart 函数负责重启NEB计算:

    dspawpy.diffusion.nebtools.restart(directory: str = '.', output: str = 'bakfile')

    Archive and compress old NEB tasks, and prepare for continuation at the original path

    参数:
    • directory -- Old NEB task path, default current path

    • output -- Backup folder path, default is to create a bakfile folder in the current path for backup; Alternatively, you can specify any path, but it cannot be the same as the current path

    示例

    >>> from dspawpy.diffusion.nebtools import restart
    >>> from shutil import copytree
    >>> copytree('dspawpy_proj/dspawpy_tests/inputs/2.15', 'dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2', dirs_exist_ok=True)
    'dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2'
    >>> restart(directory='dspawpy_proj/dspawpy_tests/outputs/doctest/neb4bk2', output='dspawpy_proj/dspawpy_tests/outputs/doctest/neb_backup')
    ==> ...neb_backup...
    

    The preparation for the continuation calculation may take a long time to complete, please be patient

  • monitor_force_energy 函数负责绘制NEB计算过程的能量和受力变化趋势图:

    dspawpy.diffusion.nebtools.monitor_force_energy(directory: str, outdir: str = '.', relative: bool = False)

    Read forces and energies during NEB calculations from xx/DS-PAW.log and plot curves

    No JSON files are output during the calculation, and only force information is present in nebXX.h5 files, so DS-PAW.log must be read.

    Energy matching mode, should hit -40521.972259

    8 LOOP 1:

    # iter | Etot(eV) dE(eV) time # 1 | -35958.655378 -3.595866e+04 47.784 s # 2 | -40069.322436 -4.110667e+03 15.146 s # 3 | -40490.281166 -4.209587e+02 15.114 s # 4 | -40521.972259 -3.169109e+01 17.936 s

    示例

    >>> from dspawpy.diffusion.nebtools import monitor_force_energy
    >>> monitor_force_energy(
    ...     directory="dspawpy_proj/dspawpy_tests/inputs/supplement/neb_unfinished",
    ...     outdir="imgs"
    ... )
    Max Force shape: (57, 4)
    ┌───────────┬───────────┬───────────┬───────────┐
    │ Folder 01 ┆ Folder 02 ┆ Folder 03 ┆ Folder 04 │
    ╞═══════════╪═══════════╪═══════════╪═══════════╡
    │ 23.775228 ┆ 71.547767 ┆ 72.641234 ┆ 24.147289 │
    │ 22.683711 ┆ 68.595607 ┆ 69.704747 ┆ 23.0549   │
    │ 5.624252  ┆ 20.071221 ┆ 20.049429 ┆ 5.567894  │
    │ 5.354774  ┆ 19.631643 ┆ 19.599093 ┆ 5.425462  │
    │ 3.188546  ┆ 9.840143  ┆ 9.748006  ┆ 2.943709  │
    │ …         ┆ …         ┆ …         ┆ …         │
    │ 0.293867  ┆ 0.812679  ┆ 0.920251  ┆ 0.573649  │
    │ 0.27249   ┆ 0.7475    ┆ 0.921836  ┆ 0.540239  │
    │ 0.299767  ┆ 0.360673  ┆ 1.174016  ┆ 0.416171  │
    │ 0.249903  ┆ 0.288985  ┆ 1.169237  ┆ 0.366117  │
    │ 0.204396  ┆ 0.518356  ┆ 0.913792  ┆ 0.300884  │
    └───────────┴───────────┴───────────┴───────────┘
    Energies shape: (57, 4)
    ┌───────────────┬───────────────┬───────────────┬───────────────┐
    │ Folder 01     ┆ Folder 02     ┆ Folder 03     ┆ Folder 04     │
    ╞═══════════════╪═══════════════╪═══════════════╪═══════════════╡
    │ -40448.281556 ┆ -40436.419243 ┆ -40436.084611 ┆ -40447.527434 │
    │ -40448.491374 ┆ -40437.026948 ┆ -40436.685178 ┆ -40447.73947  │
    │ -40451.391617 ┆ -40446.884408 ┆ -40446.613158 ┆ -40450.686918 │
    │ -40451.448662 ┆ -40447.079933 ┆ -40446.803281 ┆ -40450.743777 │
    │ -40452.126865 ┆ -40450.274376 ┆ -40449.978142 ┆ -40451.405157 │
    │ …             ┆ …             ┆ …             ┆ …             │
    │ -40452.620987 ┆ -40452.538682 ┆ -40452.230568 ┆ -40452.056262 │
    │ -40452.621777 ┆ -40452.544298 ┆ -40452.231776 ┆ -40452.055815 │
    │ -40452.620701 ┆ -40452.565649 ┆ -40452.164604 ┆ -40452.035357 │
    │ -40452.621371 ┆ -40452.569113 ┆ -40452.164784 ┆ -40452.037426 │
    │ -40452.622418 ┆ -40452.577864 ┆ -40452.141919 ┆ -40452.037885 │
    └───────────────┴───────────────┴───────────────┴───────────────┘
    ==> ...MaxForce.png...
    ==> ...Energies.png...
    

8.9 phonon声子计算数据处理

以MgO体系的声子能带态密度计算得到的 phonon.h5 为例:

如果未安装 phonopy,运行下列脚本时会弹出 no module named 'phonopy' 信息,不影响程序正常运行

声子能带数据处理

 1# coding:utf-8
 2import os
 3
 4from pymatgen.phonon.plotter import PhononBSPlotter
 5
 6from dspawpy.io.read import get_phonon_band_data
 7
 8band_data = get_phonon_band_data(
 9    "dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5",
10)  # Read phonon band structure
11bsp = PhononBSPlotter(band_data)
12axes_or_plt = bsp.get_plot(ylim=None, units="thz")  # Y-axis range # Units
13import matplotlib.pyplot as plt  # noqa: E402
14
15if isinstance(axes_or_plt, plt.Axes):
16    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
17elif isinstance(axes_or_plt, tuple):
18    fig = axes_or_plt[0].get_figure()
19else:
20    fig = axes_or_plt.gcf()  # older version pymatgen
21
22filename = "dspawpy_proj/dspawpy_tests/outputs/us/9phonon_bandplot.png"  # File name for the output phonon band plot
23os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
24fig.savefig(filename, dpi=300)

执行代码可以得到类似以下声子能带曲线:

_images/phonon-nonac.png

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

声子态密度数据处理

  • 参考 9phonon_dosplot.py

     1# coding:utf-8
     2import os
     3
     4from pymatgen.phonon.plotter import PhononDosPlotter
     5
     6from dspawpy.io.read import get_phonon_dos_data
     7
     8dos = get_phonon_dos_data("dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5")
     9dp = PhononDosPlotter(
    10    stack=False,  # True indicates drawing an area plot
    11    sigma=None,  # Gaussian blur parameter
    12)
    13dp.add_dos(
    14    label="Phonon", dos=dos
    15)  # Legend  # The phonon density of states to be plotted
    16axes_or_plt = dp.get_plot(
    17    xlim=[0, 20],  # x-axis range
    18    ylim=None,  # y-axis range
    19    units="THz",  # Unit
    20)
    21import matplotlib.pyplot as plt  # noqa: E402
    22
    23if isinstance(axes_or_plt, plt.Axes):
    24    fig = axes_or_plt.get_figure()  # version newer than v2023.8.10
    25elif isinstance(axes_or_plt, tuple):
    26    fig = axes_or_plt[0].get_figure()
    27else:
    28    fig = axes_or_plt.gcf()  # older version pymatgen
    29
    30filename = " dspawpy_proj/dspawpy_tests/outputs/us/9phonon_dosplot.png"  # Energy barrier plot output filename
    31os.makedirs(os.path.dirname(os.path.abspath(filename)), exist_ok=True)
    32fig.savefig(filename, dpi=300)
    

    执行代码可以得到类似以下声子态密度曲线:

_images/9phonon_dosplot.png

单晶硅声子态密度示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

声子热力学数据处理

可以参考 9phonon_thermal.py

1# coding:utf-8
2from dspawpy.plot import plot_phonon_thermal
3
4plot_phonon_thermal(
5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.h5",  # phonon.h5 data file path
6    figname="dspawpy_proj/dspawpy_tests/outputs/us/9phonon.png",  # Output phonon thermodynamics figure filename
7    show=False,  # Whether to display the image
8)

执行代码可以得到类似以下声子热力学曲线:

_images/9phonon.png

单晶硅声子热力学性质示意图

API: get_phonon_band_data(), get_phonon_dos_data(), plot_phonon_thermal()
  • get_phonon_band_data 函数负责读取声子能带:

    dspawpy.io.read.get_phonon_band_data(phonon_band_dir: str, verbose: bool = False)

    Reads phonon band data from an h5 or json file and constructs a PhononBandStructureSymmLine object

    参数:

    phonon_band_dir -- Path to the band structure file, phonon.h5 / phonon.json, or a folder containing these files

    返回类型:

    PhononBandStructureSymmLine

    示例

    >>> from dspawpy.io.read import get_phonon_band_data
    >>> band_data = get_phonon_band_data("dspawpy_proj/dspawpy_tests/inputs/2.16/phonon.h5") # Read phonon band data
    >>> band_data = get_phonon_band_data("dspawpy_proj/dspawpy_tests/inputs/2.16/phonon.json") # Read phonon band data
    
  • get_phonon_dos_data 函数负责读取声子态密度:

    dspawpy.io.read.get_phonon_dos_data(phonon_dos_dir: str, verbose: bool = False)

    Reads phonon density of states data from an h5 or json file, constructs a PhononDos object

    参数:

    phonon_dos_dir -- Path to the phonon DOS file, phonon_dos.h5 / phonon_dos.json, or a folder containing these files

    返回类型:

    PhononDos

    示例

    >>> from dspawpy.io.read import get_phonon_dos_data
    >>> phdos = get_phonon_dos_data(phonon_dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.json')
    >>> phdos = get_phonon_dos_data(phonon_dos_dir='dspawpy_proj/dspawpy_tests/inputs/2.16.1/phonon.h5')
    >>> phdos.frequencies
    array([ 0. ,  0.1,  0.2,  0.3,  0.4,  0.5,  0.6,  0.7,  0.8,  0.9,  1. ,
            1.1,  1.2,  1.3,  1.4,  1.5,  1.6,  1.7,  1.8,  1.9,  2. ,  2.1,
            2.2,  2.3,  2.4,  2.5,  2.6,  2.7,  2.8,  2.9,  3. ,  3.1,  3.2,
            3.3,  3.4,  3.5,  3.6,  3.7,  3.8,  3.9,  4. ,  4.1,  4.2,  4.3,
            4.4,  4.5,  4.6,  4.7,  4.8,  4.9,  5. ,  5.1,  5.2,  5.3,  5.4,
            5.5,  5.6,  5.7,  5.8,  5.9,  6. ,  6.1,  6.2,  6.3,  6.4,  6.5,
            6.6,  6.7,  6.8,  6.9,  7. ,  7.1,  7.2,  7.3,  7.4,  7.5,  7.6,
            7.7,  7.8,  7.9,  8. ,  8.1,  8.2,  8.3,  8.4,  8.5,  8.6,  8.7,
            8.8,  8.9,  9. ,  9.1,  9.2,  9.3,  9.4,  9.5,  9.6,  9.7,  9.8,
            9.9, 10. , 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9,
           11. , 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 11.8, 11.9, 12. ,
           12.1, 12.2, 12.3, 12.4, 12.5, 12.6, 12.7, 12.8, 12.9, 13. , 13.1,
           13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14. , 14.1, 14.2,
           14.3, 14.4, 14.5, 14.6, 14.7, 14.8, 14.9, 15. , 15.1, 15.2, 15.3,
           15.4, 15.5, 15.6, 15.7, 15.8, 15.9, 16. , 16.1, 16.2, 16.3, 16.4,
           16.5, 16.6, 16.7, 16.8, 16.9, 17. , 17.1, 17.2, 17.3, 17.4, 17.5,
           17.6, 17.7, 17.8, 17.9, 18. , 18.1, 18.2, 18.3, 18.4, 18.5, 18.6,
           18.7, 18.8, 18.9, 19. , 19.1, 19.2, 19.3, 19.4, 19.5, 19.6, 19.7,
           19.8, 19.9, 20. ])
    
  • plot_phonon_thermal 函数负责绘制声子热力学性质图:

    dspawpy.plot.plot_phonon_thermal(datafile: str = 'phonon.h5', figname: str = 'phonon.png', show: bool = True, raw: bool = False, verbose: bool = False)

    Task completed for phonon thermodynamic calculations, plot curves of relevant physical quantities versus temperature

    phonon.h5/phonon.json -> phonon.png

    参数:
    • datafile -- Path to an h5 or json file or a folder containing any of these files, default 'phonon.h5'

    • figname -- Filename to save the image

    • show -- Whether to pop up an interactive interface

    • raw -- Whether to save the plotting data to rawphonon.csv file

    返回:

    Image path, default 'phonon.png'

    返回类型:

    figname

    示例

    >>> from dspawpy.plot import plot_phonon_thermal
    >>> plot_phonon_thermal('dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.h5', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/phonon_thermal_h5.png', show=False)
    >>> plot_phonon_thermal('dspawpy_proj/dspawpy_tests/inputs/2.26/phonon.json', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/phonon_thermal_json.png', show=False, raw=True)
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.10 aimd分子动力学模拟数据处理

以快速入门 \(H_{2}O\) 分子体系分子动力学模拟得到的 aimd.h5 为例:

轨迹文件转换格式为.xyz或.dump

从aimd输出的hdf5文件中读取数据,并生成轨迹文件

生成的.xyz或.dump格式文件,可拖入OVITO观察,通过 Device Studio --> Simulator --> OVITO 打开 OVITO 可视化界面,将xyz文件或dump文件拖入OVITO即可。

参考 10write_aimd_traj.py

 1# coding:utf-8
 2from dspawpy.io.structure import convert
 3
 4convert(
 5    infile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Structure to be converted, if in the current path, only the filename can be written
 6    si=None,  # Filter the configuration number, if not specified, read all by default
 7    ele=None,  # Filter element symbol, default reads atomic information for all elements
 8    ai=None,  # Filter atomic indices (starting from 1), default to read all atomic information
 9    outfile="dspawpy_proj/dspawpy_tests/outputs/us/10aimdTraj.xyz",  # Can also generate .dump files (lower precision), currently only supports orthogonal unit cells
10)

执行代码将生成.xyz和.dump格式的轨迹文件,该文件可通过OVITO打开。关于结构文件转化的更多细节,请参考 structure结构转化

知识点:

OVITO 与 dspawpy 都不支持将非正交晶胞的体系保存为dump文件

动力学过程中能量、温度等变化曲线

  • 参考 10check_aimd_conv.py

     1# coding:utf-8
     2from dspawpy.plot import plot_aimd
     3
     4plot_aimd(
     5    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Data file path
     6    show=False,  # Whether to pop up the image window
     7    figname="dspawpy_proj/dspawpy_tests/outputs/us/10aimd.png",  # Output image file name
     8    flags_str="1 2 3 4 5",  # Select data types
     9)
    10# The meaning of flags_str is as follows
    11# 1. Kinetic energy
    12# 2. Total Energy
    13# 3. Pressure
    14# 4. Temperature
    15# 5. Volume
    

    执行代码将生成如下组合图:

    _images/aimd-joined.png

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

均方位移(MSD) 分析

  • 参考 10aimd_msd.py

     1# coding:utf-8
     2from dspawpy.analysis.aimdtools import get_lagtime_msd, plot_msd
     3
     4# If AIMD is not completed in one go, you can assign multiple h5 file paths to the datafile parameter in a list form
     5lagtime, msd = get_lagtime_msd(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Data file path
     7    select="all",  # Default selects all atoms
     8    msd_type="xyz",  # Default to calculate MSD in the xyz directions
     9    timestep=None,  # Default reads the timestep from the datafile
    10)
    11# Plot the graph using the obtained data and save it
    12plot_msd(
    13    lagtime,  # X-axis coordinate
    14    msd,  # vertical axis
    15    xlim=None,  # Set the display range of the x-axis
    16    ylim=None,  # Set the display range of the y-axis
    17    figname="dspawpy_proj/dspawpy_tests/outputs/us/10MSD.png",  # Output image filename
    18    show=False,  # Whether to pop up the image window
    19    ax=None,  # Optional subplot specification
    20)
    

    执行代码将生成类似如下图片:

    _images/10MSD.png

    均方位移(MSD)示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

均方根偏差(RMSD) 分析

  • 参考 10aimd_rmsd.py

     1# coding:utf-8
     2from dspawpy.analysis.aimdtools import get_lagtime_rmsd, plot_rmsd
     3
     4# If AIMD is not completed in a single run, you can assign multiple paths of h5 files in list form to the datafile parameter
     5lagtime, rmsd = get_lagtime_rmsd(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",
     7    timestep=None,  # Data file path  # Default reads the time step from the datafile
     8)
     9plot_rmsd(
    10    lagtime,  # Horizontal coordinate
    11    rmsd,  # vertical coordinate
    12    xlim=None,  # Set the display range of the x-axis
    13    ylim=None,  # Set the display range of the y-axis
    14    figname="dspawpy_proj/dspawpy_tests/outputs/us/10RMSD.png",  # Output image filename
    15    show=False,  # Whether to pop up the image window
    16    ax=None,  # Optional subplot specification
    17)
    

    执行代码将生成类似如下图片:

    _images/10RMSD.png

    均方根偏差(RMSD)示意图

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

原子对分布函数或径向分布函数(RDFs) 分析

  • 参考 10aimd_rdf.py

     1# coding:utf-8
     2from dspawpy.analysis.aimdtools import get_rs_rdfs, plot_rdf
     3
     4# If AIMD is not completed in one go, you can assign multiple h5 file paths to the datafile parameter in the form of a list.
     5rs, rdfs = get_rs_rdfs(
     6    datafile="dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5",  # Data file path
     7    ele1="H",  # Central element
     8    ele2="O",  # Target element
     9    rmin=0.0,  # Minimum radius
    10    rmax=10.0,  # Maximum radius
    11    ngrid=1000,  # Number of grid points
    12    sigma=0.1,  # sigma value
    13)
    14plot_rdf(
    15    rs,  # x-axis values
    16    rdfs,  # Vertical coordinate
    17    "H",  # Central element
    18    "O",  # Object element
    19    figname="dspawpy_proj/dspawpy_tests/outputs/us/10RDF.png",  # Image save path
    20    show=False,  # Whether to pop up the image window
    21    ax=None,  # Subplot can be specified
    22)
    

    执行代码将生成类似如下图片:

    _images/10RDF.png

    径向分布函数(RDFs)示意图

  • 这部分涉及的统计学计算较复杂,更多细节请参考函数API

API: plot_aimd(), get_lagtime_msd(), plot_msd(), get_rs_rdfs(), plot_rdf(), get_lagtime_rmsd(), plot_rmsd()
  • plot_aimd 函数可用于协助检查AIMD计算过程中关键物理量的收敛过程:

    dspawpy.plot.plot_aimd(datafile: str = 'aimd.h5', show: bool = True, figname: str = 'aimd.png', flags_str: str = '12345', raw: bool = False)

    Plot the convergence process of key physical quantities after the AIMD task completion

    aimd.h5 -> aimd.png

    参数:
    • datafile -- Location of the h5 file. For example, 'aimd.h5' or ['aimd.h5', 'aimd2.h5']

    • show -- Whether to display the interactive interface. Default is False

    • figname -- Path to the saved image. Default 'aimd.h5'

    • flags_str -- Subplot number. 1. Kinetic Energy 2. Total Energy 3. Pressure 4. Temperature 5. Volume

    • raw -- Whether to output plot data to a CSV file

    返回:

    Image path, default 'aimd.png'

    返回类型:

    figname

    示例

    >>> from dspawpy.plot import plot_aimd
    

    Read the contents of the aimd.h5 file, plot the convergence process graphs of kinetic energy, total energy, temperature, and volume, and save the corresponding data to rawaimd_*.csv.

    >>> plot_aimd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', flags_str='1 2 3 4 5', raw=True, show=False, figname="dspawpy_proj/dspawpy_tests/outputs/doctest/aimdconv.png")
    >>> plot_aimd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', flags_str='1 2 3 4 5', show=False, figname="dspawpy_proj/dspawpy_tests/outputs/doctest/aimdconv_json.png")
    
  • get_*plot_* 函数负责读取AIMD计算过程中的关键物理量:

    dspawpy.analysis.aimdtools.get_lagtime_msd(datafile: str | List[str], select: str | List[int] = 'all', msd_type: str = 'xyz', timestep: float | None = None)

    Calculate the mean squared displacement at different time steps

    参数:
    • datafile --

      • Path to aimd.h5 or aimd.json files, or a directory containing these files (prioritizes searching for aimd.h5)

      • Written as a list, the data will be read sequentially and merged together

      • For example ['aimd1.h5', 'aimd2.h5', '/data/home/my_aimd_task']

    • select -- Select atomic number or element; atomic numbers start from 0; default is 'all', which calculates all atoms

    • msd_type -- Calculate the type of MSD, options: xyz, xy, xz, yz, x, y, z, default is 'xyz', which calculates all components

    • timestep -- Time interval between adjacent structures, in units of fs, default None, will be read from datafile, if failed, set to 1.0fs; If not None, this value will be used to calculate the time series

    返回:

    • lagtime (np.ndarray) -- Time series

    • result (np.ndarray) -- Mean square displacement sequence

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_msd
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', timestep=0.1)
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5')
    Calculating MSD...
    >>> lagtime
    array([0.000e+00, 1.000e+00, 2.000e+00, ..., 1.997e+03, 1.998e+03,
           1.999e+03])
    >>> msd
    array([0.00000000e+00, 3.75844096e-03, 1.45298732e-02, ...,
           7.98518472e+02, 7.99267490e+02, 7.99992702e+02])
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select='H')
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', select=[0,1])
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select=['H','O'])
    Calculating MSD...
    >>> lagtime, msd = get_lagtime_msd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', select=0)
    Calculating MSD...
    
    dspawpy.analysis.aimdtools.get_lagtime_rmsd(datafile: str | List[str], timestep: float | None = None)
    参数:
    • datafile --

      • Path to aimd.h5 or aimd.json files, or a directory containing these files (prioritizes searching for aimd.h5).

      • Written as a list, the data will be read sequentially and merged together

      • For example ['aimd1.h5', 'aimd2.h5', '/data/home/my_aimd_task']

    • timestep -- Time interval between adjacent structures, in fs, default None, will be read from datafile, set to 1.0fs if failed; If not None, it will be used to calculate the time series

    返回:

    • lagtime (numpy.ndarray) -- Time series

    • rmsd (numpy.ndarray) -- Root mean square deviation sequence

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_rmsd
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json')
    Calculating RMSD...
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', timestep=0.1)
    Calculating RMSD...
    >>> lagtime
    array([0.000e+00, 1.000e-01, 2.000e-01, ..., 1.997e+02, 1.998e+02,
           1.999e+02])
    >>> rmsd
    array([ 0.        ,  0.05321816,  0.09771622, ..., 28.27847679,
           28.28130893, 28.28414224])
    
    dspawpy.analysis.aimdtools.get_rs_rdfs(datafile: str | List[str], ele1: str, ele2: str, rmin: float = 0, rmax: float = 10, ngrid: int = 101, sigma: float = 0)

    Compute the radial distribution function (RDF).

    参数:
    • datafile --

      • Path to aimd.h5 or aimd.json files, or a directory containing these files (prioritizes searching for aimd.h5)

      • Written as a list, the data will be read sequentially and merged together

      • For example ['aimd1.h5', 'aimd2.h5', '/data/home/my_aimd_task']

    • ele1 -- Central element

    • ele2 -- Adjacent elements

    • rmin -- Radial distribution minimum value, default is 0

    • rmax -- Radial distribution maximum value, default is 10

    • ngrid -- Number of grid points in the radial distribution, default is 101

    • sigma -- Smoothing parameter

    返回:

    • r (numpy.ndarray) -- Grid points for the radial distribution

    • rdf (numpy.ndarray) -- Radial distribution function

    示例

    >>> from dspawpy.analysis.aimdtools import get_rs_rdfs
    >>> rs, rdfs = get_rs_rdfs(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5',ele1='H',ele2='O', sigma=1e-6)
    Calculating RDF...
    >>> rs, rdfs = get_rs_rdfs(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5',ele1='H',ele2='O')
    Calculating RDF...
    >>> rdfs
    array([0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.00646866,
           0.01098199, 0.0004777 , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        , 0.        , 0.        , 0.        , 0.        ,
           0.        ])
    
    dspawpy.analysis.aimdtools.plot_msd(lagtime, result, xlim: Sequence | None = None, ylim: Sequence | None = None, figname: str | None = None, show: bool = True, ax=None, **kwargs)

    Compute mean squared displacement (MSD) after the AIMD task is completed

    参数:
    • lagtime (np.ndarray) -- Time series

    • result (np.ndarray) -- Mean squared displacement sequence

    • xlim -- x-axis range, default None, set automatically

    • ylim -- y-axis range, default to None, automatically set

    • figname -- Image name, default to None, do not save the image

    • show -- Whether to display the image, default is True

    • ax -- Used to draw the image on a subplot in matplotlib

    • **kwargs (dict) -- Other parameters, such as line width, color, etc., are passed to plt.plot function

    返回类型:

    Image after MSD analysis

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_msd, plot_msd
    

    Specify the location of the h5 file, use the get_lagtime_msd function to obtain data, and the select parameter selects the nth atom (not by element)

    >>> lagtime, msd = get_lagtime_msd('dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', select=[0])
    Calculating MSD...
    

    Plot the data and save the figure

    >>> plot_msd(lagtime, msd, xlim=[0,800], ylim=[0,1000], figname='dspawpy_proj/dspawpy_tests/outputs/doctest/MSD.png', show=False)
    ==> ...MSD.png
    ...
    
    dspawpy.analysis.aimdtools.plot_rdf(rs, rdfs, ele1: str, ele2: str, xlim: Sequence | None = None, ylim: Sequence | None = None, figname: str | None = None, show: bool = True, ax=None, **kwargs)

    Post-AIMD analysis of rdf and plotting.

    参数:
    • rs (numpy.ndarray) -- Radial distribution grid points

    • rdfs (numpy.ndarray) -- Radial distribution function

    • ele1 -- Center element

    • ele2 -- Adjacent elements

    • xlim -- x-axis range, default to None, i.e., set automatically

    • ylim -- y-axis range, default to None, i.e., automatically set

    • figname -- Image name, default to None, meaning no image is saved

    • show -- Whether to display the image, default to True

    • ax (matplotlib.axes.Axes) -- Axis for plotting, default is None, which means creating a new axis

    • **kwargs (dict) -- Other parameters, such as line width, color, etc., are passed to plt.plot function

    返回类型:

    Image after RDF analysis

    示例

    >>> from dspawpy.analysis.aimdtools import get_rs_rdfs, plot_rdf
    

    First obtain the rs and rdfs data as the x and y axis data

    >>> rs, rdfs = get_rs_rdfs('dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', 'H', 'O', rmax=6)
    Calculating RDF...
    

    Passing x and y data to the plot_rdf function to plot

    >>> plot_rdf(rs, rdfs, 'H','O', xlim=[0, 6], ylim=[0, 0.015],figname='dspawpy_proj/dspawpy_tests/outputs/doctest/RDF.png', show=False)
    ==> ...RDF.png
    
    dspawpy.analysis.aimdtools.plot_rmsd(lagtime, result, xlim: Sequence | None = None, ylim: Sequence | None = None, figname: str | None = None, show: bool = True, ax=None, **kwargs)

    Post-AIMD analysis of RMSD and plotting

    参数:
    • lagtime -- Time series

    • result -- Root mean square deviation sequence

    • xlim -- x-axis range

    • ylim -- y-axis range

    • figname -- Image save path

    • show -- Whether to display the image

    • ax (matplotlib.axes._subplots.AxesSubplot) -- If plotting subplots, pass the subplot object

    • **kwargs (dict) -- Parameters passed to plt.plot

    返回类型:

    Image of RMSD analysis of structures

    示例

    >>> from dspawpy.analysis.aimdtools import get_lagtime_rmsd, plot_rmsd
    

    timestep represents the time step length

    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.h5', timestep=0.1)
    Calculating RMSD...
    >>> lagtime, rmsd = get_lagtime_rmsd(datafile='dspawpy_proj/dspawpy_tests/inputs/2.18/aimd.json', timestep=0.1)
    Calculating RMSD...
    

    Saving directly as RMSD.png image

    >>> plot_rmsd(lagtime, rmsd, xlim=[0,200], ylim=[0, 30],figname='dspawpy_proj/dspawpy_tests/outputs/doctest/RMSD.png', show=False)
    ==> ...RMSD.png
    ...
    
  • 提取数据自行处理请参考:

     1from dspawpy.io.read import get_sinfo
     2from dspawpy.io.structure import read
     3
     4aimd_h5_files = ['aimd1.h5','aimd2.h5','aimd3.h5'] # 可以从计算完成的多个 aimd.h5 中依次抽取数据并合并
     5
     6# 一次性读取多个aimd.h5文件中的数据并创建pymatgen的Structures列表
     7pymatgen_structures = read(datafile=aimd_h5_files)
     8
     9# 或者将数组提取出来
    10for i, df in enumerate(aimd_h5_files): # 依次获取每个aimd.h5文件的数据
    11    Nstep, elements, positions, lattices, D_mag_fix = get_sinfo(df)
    12    # Nstep 表示总离子步数 (int)
    13    # elements 表示元素列表,(Natom x 1)
    14    # positions 表示离子坐标,(Nstep x Natom x 3)
    15    # lattices 表示晶胞矩阵,(Nstep x 3 x 3
    16    # D_mag_fix 磁矩、自由度相关信息字典
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.11 Polarization铁电极化数据处理

以快速入门 \(HfO_{2}\) 体系铁电计算得到的系列 scf.h5 为例:

  • 参考 11Ferri.py

    1# coding:utf-8
    2from dspawpy.plot import plot_polarization_figure
    3
    4plot_polarization_figure(
    5    directory="dspawpy_proj/dspawpy_tests/inputs/2.20",  # Path for iron polarization calculation
    6    repetition=2,  # Number of times to repeat the data points when plotting
    7    figname="dspawpy_proj/dspawpy_tests/outputs/us/11pol.png",  # Output polarization figure filename
    8    show=False,  # Whether to display the polarization figure
    9)  # --> pol.png
    

    执行代码将生成如下组合图:

    _images/11pol.png

    12组结构对应极化数值

    查看首尾构型的铁电极化数值,可以参考如下:

    1from dspawpy.plot import plot_polarization_figure
    2
    3plot_polarization_figure(directory='.', annotation=True, annotation_style=1) # 显示首尾构型的铁电极化数值
    

    执行代码将生成如下组合图:

    _images/Ferri-Pola-anno1.png

    12组结构对应极化数值(带首尾构型数值)

    也可以使用第二种批注样式:

    1from dspawpy.plot import plot_polarization_figure
    2
    3plot_polarization_figure(directory='.', annotation=True, annotation_style=2) # 显示首尾构型的铁电极化数值
    

    执行代码将生成如下组合图:

    _images/Ferri-Pola-anno2.png

    12组结构对应极化数值(带首尾构型数值)

API: plot_polarization_figure()
  • plot_polarization_figure 函数负责绘制铁电极化图:

    dspawpy.plot.plot_polarization_figure(directory: str, repetition: int = 2, annotation: bool = False, annotation_style: int = 1, show: bool = True, figname: str = 'pol.png', raw: bool = False)

    Plot the polarization results of the iron electrode

    参数:
    • directory -- Main directory for the iron polarization calculation task

    • repetition -- Number of times to repeat drawing along the upper (or lower) direction, default 2

    • annotation -- Whether to display the polarization values of the iron electrodes at the beginning and end configurations, displayed by default

    • show -- Interactive display of the image, default True

    • figname -- Image save path, default 'pol.png'

    • raw -- Whether to save the raw data to a CSV file

    返回:

    axes -- Can be passed to other functions for further processing

    返回类型:

    matplotlib.axes._subplots.AxesSubplot

    示例

    >>> from dspawpy.plot import plot_polarization_figure
    >>> result = plot_polarization_figure(directory='dspawpy_proj/dspawpy_tests/inputs/2.20', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/pol1.png', show=False, annotation=True, annotation_style=1)
    >>> result = plot_polarization_figure(directory='dspawpy_proj/dspawpy_tests/inputs/2.20', figname='dspawpy_proj/dspawpy_tests/outputs/doctest/pol2.png', show=False, annotation=True, annotation_style=2)
    

警告

如果通过SSH连接到远程服务器执行上述脚本,出现QT相关的报错信息,可能是使用的程序(比如MobaXterm等)和QT库不兼容,要么更换程序(例如VSCode或者系统自带的终端命令行),要么请在python脚本第二行开始添加以下代码:

import matplotlib
matplotlib.use('agg')

8.12 ZPE零点振动能数据处理

以快速入门 \(CO\) 体系频率计算得到的 frequency.txt 文件为例,计算零点振动能,基于以下公式:

\[ZPE=\sum_{i=1}^{3 N} \frac{h \nu_i}{2}\]

其中, \(\nu_i\) 是简正频率, \(h\) 是普朗克常数( \(6.626\times10^{-34} J\cdot s\)), \(N\) 是原子数。

  • 参考 12getZPE.py

    1# coding:utf-8
    2from dspawpy.io.utils import getZPE
    3
    4# Import the frequency.txt file obtained from frequency calculation
    5getZPE(
    6    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
    7)
    

    执行代码结果文件将保存到 ZPE.dat 文件中,文件内容如下:

    Data read from D:\quickstart\2.13\frequency.txt
    Frequency (meV)
    284.840038
    
    --> Zero-point energy,  ZPE (eV): 0.142420019
    
API: getZPE()
  • getZPE 函数负责计算零点振动能:

    Some functions are extracted from [ase](https://wiki.fysik.dtu.dk/ase/index.html).

    dspawpy.io.utils.getZPE(fretxt: str = 'frequency.txt')

    Read data from fretxt, calculate ZPE

    The results will also be saved to ZPE_TS.dat.

    参数:

    fretxt -- Path to the file recording frequency information, default to 'frequency.txt' in the current path

    返回:

    Zero-point energy

    返回类型:

    ZPE

    示例

    >>> from dspawpy.io.utils import getZPE
    >>> ZPE=getZPE(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt')
    --> Zero-point energy,  ZPE (eV): 0.1424200165
    

8.13 TS的热校正能

吸附质的熵变对能量的贡献

计算基于以下公式:

\[\Delta S_{a d s}\left(0 \rightarrow T, P^0\right)=S_{v i b}=\sum_{i=1}^{3 N}\left[\frac{N_{\mathrm{A}} h \nu_i}{T\left(e^{h \nu_i / k_{\mathrm{B}} T}-1\right)}-R \ln \left(1-e^{-h \nu_i / k_{\mathrm{B}} T}\right)\right]\]

其中, \(\Delta S_{a d s}\) 表示吸附质的熵变,根据简谐近似计算。\(S_{v i b}\) 表示振动熵。 \(\nu_i\) 是简正频率,\(N_A\) 是阿伏伽德罗常数( \(6.022\times10^{23} mol^{-1}\) ), \(h\) 是普朗克常数( \(6.626\times10^{-34} J\cdot s\)), \(k_B\) 是玻尔兹曼常数( \(1.38\times10^{-23} J\cdot K^{-1}\)), \(R\) 是理想气体常数( \(8.314 J\cdot mol^{-1}\cdot K^{-1}\)), \(T\) 是体系温度,单位 \(K\)

  • 参考 13getTSads.py

    1# coding:utf-8
    2from dspawpy.io.utils import getTSads
    3
    4# Import the frequency.txt file calculated from frequency, temperature can be modified arbitrarily
    5getTSads(
    6    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
    7    T=298.15,
    8)
    

    执行代码结果文件将保存到 TS.dat 文件中,文件内容如下:

    Data read from D:\quickstart\2.13\frequency.txt
    Frequency (THz)
    68.873994
    
    --> Entropy contribution,  T*S (eV): 4.7566990201851275e-06
    

理想气体的熵变对能量的贡献

计算基于如下公式:

\[\begin{split}\begin{aligned} S(T, P) & =S\left(T, P^{\circ}\right)-k_{\mathrm{B}} \ln \frac{P}{P^{\circ}} \\ & =S_{\text {trans }}+S_{\text {rot }}+S_{\text {elec }}+S_{\text {vib }}-k_{\mathrm{B}} \ln \frac{P}{P^{\circ}} \end{aligned}\end{split}\]

其中:

\[S_{\text {trans }}=k_{\mathrm{B}}\left\{\ln \left[\left(\frac{2 \pi M k_{\mathrm{B}} T}{h^2}\right)^{3 / 2} \frac{k_{\mathrm{B}} T}{P^{\circ}}\right]+\frac{5}{2}\right\}\]
\[\begin{split}S_{\mathrm{rot}}= \begin{cases}0 & \text {, monatomic } \\ k_{\mathrm{B}}\left[\ln \left(\frac{8 \pi^2 I k_{\mathrm{B}} T}{\sigma h^2}\right)+1\right] & \text {, linear } \\ k_{\mathrm{B}}\left\{\ln \left[\frac{\sqrt{\pi I_A I_{\mathrm{B}} I_{\mathrm{C}}}}{\sigma}\left(\frac{8 \pi^2 k_B T}{h^2}\right)^{3 / 2}\right]+\frac{3}{2}\right\} & \text {, nonlinear }\end{cases}\end{split}\]
\[S_{\text {elec }}=k_{\mathrm{B}} \ln [2 \times(\text { total spin })+1]\]
\[S_{\text {vib }}=k_{\mathrm{B}} \sum_i^{\text {vib DOF }}\left[\frac{\epsilon_i}{k_{\mathrm{B}} T\left(e^{\epsilon_i / k_{\mathrm{B}} T}-1\right)}-\ln \left(1-e^{-\epsilon_i / k_{\mathrm{B}} T}\right)\right]\]

其中:\(I_A\)\(I_C\) 是非线性分子的三个主惯性矩, \(I\) 是线性分子的简并惯性矩, \(\sigma\) 是分子的对称数。另外,monatomic 表示单原子分子,linear 表示线性分子,nonlinear 表示非线性分子。total spin 是总自旋数。 vib DOF 表示振动自由度。

  • 参考 13getTSgas.py 脚本处理:

     1# coding:utf-8
     2from dspawpy.io.utils import getTSgas
     3
     4# Read elements and coordinates from the calculation result file (json or h5)
     5TSgas = getTSgas(
     6    fretxt="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt",
     7    datafile="dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.h5",
     8    potentialenergy=-0.0,
     9    geometry="linear",
    10    symmetrynumber=1,
    11    spin=1,
    12    temperature=298.15,
    13    pressure=101325.0,
    14)
    15print("Entropy contribution, T*S (eV):", TSgas)
    16
    17# If only the frequency.txt file is available, the calculation can be completed by manually specifying the elements and coordinates
    18# TSgas = getTSgas(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', datafile=None, potentialenergy=-0.0, elements=['H', 'H'], geometry='linear', positions=[[0.0, 0.0, 0.0], [0.0, 0.0, 1.0]], symmetrynumber=1, spin=1, temperature=298.15, pressure=101325.0)
    
API: getTSads(), getTSgas()
  • getTSads 函数负责计算吸附质熵变对能量的贡献:

    Some functions are extracted from [ase](https://wiki.fysik.dtu.dk/ase/index.html).

    dspawpy.io.utils.getTSads(fretxt: str = 'frequency.txt', T: float = 298.15)

    Read data from fretxt, calculate ZPE and TS

    Will also save the results to TSads.dat

    参数:
    • fretxt -- Path to the file recording frequency information, default 'frequency.txt' in the current path

    • T -- Temperature, unit K, default 298.15

    返回:

    Entropy correction

    返回类型:

    TS

    示例

    >>> from dspawpy.io.utils import getTSads
    >>> TSads=getTSads(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', T=298.15)
    --> T*S (eV): 4.7566997225177686e-06
    
  • getTSgas 函数负责计算理想气体熵变对能量的贡献:

    Some functions are extracted from [ase](https://wiki.fysik.dtu.dk/ase/index.html).

    dspawpy.io.utils.getTSgas(fretxt='frequency.txt', datafile='.', potentialenergy: float = 0.0, elements=None, geometry='linear', positions=None, symmetrynumber=1, spin=1, temperature=298.15, pressure: float = 101325, verbose: bool = False)

    Energy contribution to entropy under the ideal gas approximation"

    参数:
    • fretxt -- Path to the file recording frequency information, default is 'frequency.txt' in the current path

    • datafile -- Path to the JSON or h5 file or folder containing them, default to the current path; If set to None, the elements and positions parameters must be provided

    • potentialenergy -- Potential energy, unit eV

    • elements -- List of elements, if

    • geometry -- Molecular geometry, monatomic, linear, nonlinear

    • positions -- Atomic coordinates, unit Angstrom

    • symmetrynumber -- Symmetry number

    • spin -- Spin number

    • temperature -- Temperature, unit K

    • pressure -- Pressure, unit Pa

    返回:

    Under the ideal gas approximation, calculates the energy contribution to entropy, in units of eV

    返回类型:

    TSgas

    示例

    >>> from dspawpy.io.utils import getTSgas
    >>> TSgas=getTSgas(fretxt='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.txt', datafile='dspawpy_proj/dspawpy_tests/inputs/2.13/frequency.h5', potentialenergy=-0.0,  geometry='linear', symmetrynumber=1, spin=1, temperature=298.15, pressure=101325.0)
    --> T*S (eV): 0.8515317035550232
    

8.14 附录